Re: [Haskell-cafe] US Patent for the idea of using Haskell to implement UAX #9
Daniel Fischer wrote: Am Freitag 16 April 2010 20:50:25 schrieb Brian Hulley: revealed a link to a US Patent (7120900) for the idea of implementing the Unicode Bidirectional Algorithm (UAX #9 http://www.unicode.org/reports/tr9) in Haskell, making use, as far as I can tell, of nothing more than the normal approach any functional programmer would use, namely separation of concerns etc. In which case the patent should be null and void since obvious ideas aren't patentable, AFAIK. But of course, IANAL, you never know what jurists think a law means, ... Hi Daniel, Thanks for your reply. The main problem for me is just the fact that the legal system in itself is, as Charles Dickens wrote in The Old Curiosity Shop (Chapter 37): ... an edged tool of uncertain application, very expensive in the working, and rather remarkable for its properties of close shaving, than for its always shaving the right person. I just think somehow we should be free to write any programs we want just like composers can compose music, (as long as we don't just copy other people's actual copyrighted *code* without their permission of course). After all, there is no reason why people couldn't just keep their ideas a secret if they don't want others to use them: at least it wouldn't spoil things for everyone else. Companies could even charge for *access* to these secrets and people could sign NDAs, but this isn't the same as being allowed to actually own an idea itself. The current situation is a bit like a supermarket throwing oranges and apples at passers-by, then forcing people to pay if they were hit... In any case after signing the petition I'm going to just try and forget about the problem! ;-) Cheers, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: US Patent for the idea ...
jerzy.karczmarc...@info.unicaen.fr wrote: Brian Hulley reports a search similar to : haskell unicode bidirectional Comment irrelevant to Haskell, sorry. Everybody does his/her various jobs. But I lost all respect due to people who work in the US Patent Office, when I saw the patent 6,025,810, a patent for an antenna which sends signals faster than light, using some mysterious new dimension. Or the U.S. Patent 6,960,975 for an anti-gravity device. It seems that although it is illegal to break some local regulations, the idea of breaking fundamental physical laws remains perfectly legal. (In some countries...) Somebody finally decided to ridiculise the system. If you want a good laugh, see the patent 6,368,227. The search site is here: http://patft.uspto.gov/netahtml/PTO/srchnum.htm Best regards. Jerzy Karczmarczuk ... Hi Jerzy, Yes that one is very funny. Also the existence of the other patents just show how ridiculous the system is. So thanks, that humour has helped me get back down to earth and away from all kinds of fruitless imaginations about the state of the world. I think my mind is best suited to functional programming *only*... ;-) Cheers, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: US Patent for the idea ...
Murray Gross wrote: On Sat, 17 Apr 2010, Brian Hulley wrote: see the patent 6,368,227. The search site is here: http://patft.uspto.gov/netahtml/PTO/srchnum.htm Best regards. Jerzy Karczmarczuk ... It's really almost not fair to cite that particular patent, since, if I recall the story correctly (I may be wrong in small detail, but I am sure of the general picture), that patent was filed by an attorney as a demonstration to his son how the system works. It was never filed as a serious patent. Yes, it may show how poorly the examiners are doing their job, but I think this particular patent really doesn't reflect on the poor service we are currently receiving from the entire patent system--I would like to think that the examiner knew perfectly well that this patent was not serious and was willing to play along. Hi Murray, Point taken about patent 6,368,227. I think in all fairness to examiners that in a way they have an impossible job due to the fact that what is a clever idea to one programmer will be a trivial idea to another: the field is so huge and people have such different experiences. Coming back to patent 6,368,227 one could perhaps look past the humour and see it as a kind of indication of what the patent system is trying to do to humanity. I just mean to see this dispassionately as an image, and by trying to do I'm just anthropomorphizing what I see as a purely structural phenomenon that in itself is like a force of nature, that emerges from the inevitable incompleteness of people's understandings even if each person individually is trying to do what they feel is right. In terms of a way forward for research companies I think there is a lot of well-paid work to be found in designing and implementing useful libraries of functionality, and then licensing them for inclusion in other programs. After all, end users want a real implementation not just an idea, and it is surely much easier to trade implementations rather than to try to trade the rather nebulous concept of ideas. This would allow programmers full freedom to implement whatever they like together with the clear advantage of being able to license well designed third-party libraries: we'd have total clarity and freedom. Anyway I've said enough about software patents so I'll leave the discussion here and reiterate that all I want is for people to be able to write programs without a Sword of Damocles hanging over their heads. Cheers, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] US Patent for the idea of using Haskell to implement UAX #9
Hi everyone, It's been a long time since I last posted to this list since I'm currently working on something that is not directly Haskell-related, but it still relates to functional programming in general. Anyway imagine my surprise when an innocent search for some keywords (I can't remember the exact ones but the following gives similar results) haskell unicode bidirectional revealed a link to a US Patent (7120900) for the idea of implementing the Unicode Bidirectional Algorithm (UAX #9 http://www.unicode.org/reports/tr9) in Haskell, making use, as far as I can tell, of nothing more than the normal approach any functional programmer would use, namely separation of concerns etc. The link is http://www.freepatentsonline.com/7120900.html though I think it would be better if they had just called the website free handcuffs online because that is what it amounts to when people succeed in preventing others from using ideas, especially ideas everyone would easily think up by themselves. Before going further I would like to explicitly state that I would not wish to cast any aspersions upon the people or companies involved in this patent, since it is all too clear to me that these people have acted in a perfectly legal way and are just doing their various jobs: in other words it's an I'm a lumberjack and I'm ok... kind of scenario: everyone probably thinks of themsevles as being a perfectly nice upstanding person, and if I met any of them face to face I'm sure I would find that they are *indeed* really nice friendly people who believe that they are doing absolutely the right and logical thing. In fact many nice people I myself have talked to about my own ideas immediately suggest that I should obviously patent them: it takes a long time to explain to them why this would not actually further my goals at all, and it is difficult for them to understand my explanation because the problem is rather too subtle for people who have not already been thinking along these lines for a while. However all this does not affect the problem that this patent acts as a brick in the general structural evil in our world today: anyone who is trying to create a programming language environment that is accessible to people who use right-to-left languages is now between a rock and a hard place when it comes to implementing UAX #9, the standard Unicode algorithm for implementing the Unicode semantics of bidirectional text. In this particular case, I expect (but I'm not a lawyer so please don't take this as solid advice: it's just a hope) that a workaround for Haskell programmers would be to discard their natural desire to use a functional approach and instead just implement UAX #9 verbatim using the ST monad. (The patent also tries to extend itself to other functional languages so caution is needed all round.) But although the above workaround *might* be legal in this particular instance it seems to me that as programmers we must not just let our craft be dominated by the psychopathic tendencies of certain elements in society that work hard to try to squash the ``normals'' into a life of brutal misery while they rampage ruthlessly about with a biological inability to experience empathy for other human beings. (www.ponerology.com) The memetic virus of psychopathy is rapidly spreading throughout human civilization and most people are not conscious enough of the elements that are contributing towards their own behaviour, thus ignoring the fact that the rice they eat for supper might have been picked by a tiny little girl in China with bleeding fingers or the carpet they walk on may have been made by a little 8 year old boy slave chained all day to a loom in a shed in India. To this end I humbly appeal to everyone here to please help in the fight against software patents, so that we can begin the huge task of reclaiming our world for real people who understand that true meaning in life comes from extending our feeling of self into the world beyond our own body: http://petition.stopsoftwarepatents.eu/ http://ffii.org Thanks a lot for reading this, Brian. [expecting to be crucified, but if it helps just one little girl or boy it will be worth it!] Disclaimer: this email is entirely my responsibility and I am not acting on behalf of any of the above web sites. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Looking for a more functional way to do this
Jefferson Heard wrote: Adrian, my understanding is that it's not that simple, because I need to preserve the state between calls to GLUT's callbacks, which all return IO (). 2008/8/6 Adrian Neumann [EMAIL PROTECTED]: There is the State Monad... data ProgramState = ProgramState { some_associative_data :: Map String String , position :: GL.Vector3 Float , look_at :: GL Vector3 Float , selectables :: Map GLuint NamedObject } render :: IORef ProgramState - IO () You might find it easier to think in terms of a Reader monad where each component of your ProgramState above is now a separate IORef. Then you can just use a function: mkCallback :: ReaderT ProgramStateRefs IO () - IO () to create the necessary callbacks for GLUT, and there is no need to interleave any state between calls (since it's all kept in the IO monad directly). Eg: data ProgramStateRefs = ProgramStateRefs { some_associative_data :: IORef (Map String String) , ... } main = do r - createProgramStateRefs let mkCallback :: ReaderT ProgramStateRefs IO a - IO a mkCallback (ReaderT r_ma) = r_ma r GLUT.renderCallback $= mkCallback onRender ... onRender :: ReaderT ProgramStateRefs IO () onRender = do ... You can then go further and use phantom types to build specialized monads by newtyping the (ReaderT ProgramStateRefs IO) to limit the operations possible in each callback (e.g. to prevent calls to rendering methods inside a keyboard handler etc) though at some point there is a tradeoff between how much you really need to enforce statically and how much time you have to devise suitable schemes of phantom type parameters to enforce it. (Disclaimer: the above code is untested and may contain errors ;-) ) Regards, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Capitalization and associated type families
Jonathan Cast wrote: It's weird. ML-derived languages are functional languages at the value level (and have regular lambda-bound variables in consequence), but are logical languages at the type level (and have logical variables in consequence). So ordinary lambda-bound variables, like in ML-style functors (parametrized modules) act more like type constants than like type variables. Thanks - the above seems to be a promising avenue of thought to arrive at clarity regarding case distinctions at the type level, and I can see here the basis for a good argument of why there would actually be no inconsistency regarding the use of capitals for module type members and lowercase for the class parameters. Perhaps this is also the root of the difference between associated type synonyms and class params. Ie at the type level, uppercase == functional variable (aka constant) and lowercase == logic variable... The type level now seems to me to be quite significantly more complicated than the value level due to the mixing of functional and logic programming, not to mention that at the type level variables in an outer scope become constants in an inner scope as far as pattern matching is concerned whereas for value patterns variables are always fresh and never scoped (over other patterns). Therefore I've decided to deal with the issue of case at each level separately since it seems immediately clear that the case distinction at the value level, as in Haskell/OCaml/Moby, is obviously good due to the foolproof nature of value patterns you pointed out, whereas at the type level it may also be good but I'll need a few more months to think about it... ;-) Cheers, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Capitalization and associated type families
Tillmann Rendel wrote: Brian Hulley wrote: class Foo a where f :: a - b - (a, b) Here there is no capitalization distinction in the type of (f) but the implementation can still insert the forall b. since (a) is already in scope. Therefore similarly, if type constructors like List were instead written using lowercase, since they would already be in scope it would be clear even without explicit quantifiers that (a) and (b), but not (list), were to be quantified in the type of (map) (assuming of course that there was no top level data decl for (a) or (b)). So adding b to the export list of an imported module would change the type of f? Yes, if the module in which the above class decl were defined imported a data type (b) from some other module (or defined it elsewhere in the same module) then (f)'s type would change. (Of course at the moment this can't happen because (b) is lowercase so it can't be introduced by data/type decls or imported/exported.) The type of (f) would also change if Haskell were extended to support nested classes: class Bar b where class Foo a where f :: a - b - (a, b) But as Jonathan pointed out this behaviour is not really all that ideal since even in Haskell at the moment a simple spelling mistake could cause silent quantification instead of an error (which is perhaps the main justification for why constructors introduced by data/type decls must currently be capitalized -- unfortunately there is no corresponding protection when writing types inside class decls): class Zap a where g :: a - ^ oops! Cheers - Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Capitalization and associated type families
Hi, I'm familiar with the capitalization rules for identifiers in Haskell and know that they are very useful and practical e.g. by allowing variables to be distinguished from constants in patterns etc. However I'm trying to understand on a much deeper level whether or not they can really be justified and indeed if there is a danger that they can lead to inconsistency in the light of future extensions to the language. For example, why is there any distinction between a type variable and a type constant? To make this clearer consider the type of (map): (a - b) - List a - List b (ignoring the special [] syntax for list types which would just confuse the issue here). With explicit quantifiers, we'd write: forall a b. (a - b) - List a - List b Now this begs the question: why does List need to start with a capital? (supposing that quantifiers were always written explicitly) The same distinction between constants and variables is also used in predicate logic e.g. On(x, Table) Colour(x, Red) but similarly the above could surely be written just as easily by: exists x. on(x, table) colour(x, red) where (on), (table), (colour), and (red) are just considered to be variables that have already been introduced (by some enclosing scope) instead of having to think of them as constants and make a distinction between constant and variable. Anyway to get to the point of this post what I'm really trying to find is some explanation of why there is the concept of constant as opposed to variable or whether this concept is now redundant in the light of lexical scoping/ explicit quantification? Somewhat related to this issue is the syntax of associated type families. For example in section 5.2.2 of http://www.haskell.org/haskellwiki/GHC/Indexed_types there is the example: class C a b where data T a which raises in my mind several questions: 1) Why is (T) given a parameter? I.e. why does an associated type declared inside a class decl not automatically get all the parameters of the class passed to it so that one would just write: class C a b where data T f :: T - T === data family T a b class C a b where ... f :: T a b - T a b 2) Compare: class C a b t | a b - t with class C a b where data T In other words, why is (T) a constant when it is declared inside the class but a variable when passed as a parameter? Is the fact that (T) needs to be given a parameter even when it is declared inside the scope of the class type parameters the result of needing to fulfill the idea of constant vs variable? 3) In the syntax: class C a b data T a it seems rather odd that the a in T a should be related to the a in C a b since one might expect that the name chosen for a parameter should be local to the data decl. Apologies for such a rambling post. I've spent literally at least 6 months scouring the internet trying to find a real discussion about capitalization rules because I'm trying to answer the following question: if I make use of a similar capitalization rule in my own language, can I guarantee that this rule will not lead to an inconsistency at some future point? Ie is there a real rock solid theoretical basis for making a distinction between constants and variables that holds even in the presence of lexical scoping? Thanks, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Capitalization and associated type families
Jonathan Cast wrote: On Mon, 2008-08-04 at 19:51 +0100, Brian Hulley wrote: For example, why is there any distinction between a type variable and a type constant? forall a b. (a - b) - List a - List b Now this begs the question: why does List need to start with a capital? (supposing that quantifiers were always written explicitly) AFAIK, it doesn't; the variable/constant distinction is just there to let the implementation put the foralls in for you. Hi Jonathan - thanks - this confirms what I've been thinking. However consider: class Foo a where f :: a - b - (a, b) Here there is no capitalization distinction in the type of (f) but the implementation can still insert the forall b. since (a) is already in scope. Therefore similarly, if type constructors like List were instead written using lowercase, since they would already be in scope it would be clear even without explicit quantifiers that (a) and (b), but not (list), were to be quantified in the type of (map) (assuming of course that there was no top level data decl for (a) or (b)). Similarly, if we had explicit foralls on equations, we could say forall n x xn. drop (n+1) (x:xn) = drop n xn but forall n. drop n nil = nil and it would be perfectly clear that `nil' in the latter case was a constructor. Actually I quite like the above because it shows that pattern matching can be understood in terms of universally quantified predicates. Regarding the verbosity, patterns are something of a special case since variables (that are introduced in the pattern) can only occur once and there is no need to have higher rank quantification in value patterns (disregarding explicit tests for _|_). Therefore special syntax could be used to make the above shorter e.g. borrowing the '?' from Felix (http://felix.sourceforge.net/doc/tutorial/introduction/en_flx_tutorial_top.html (section 2.11/2.17 etc)): drop (?n + 1) (_ : ?xn) = drop n xn drop ?n nil = nil (where glued prefix binds tighter than application). Of course, if you want to introduce this rule, you'd better start out with it and be consistent --- require every variable to be explicitly brought into scope. I think you'd find it pretty annoying after trying to program in your new language for a while, though. I agree that there are many good points in favour of Haskell's use of a case distinction, not the least being that it gives definite guidance on when to use lower or upper case identifiers and therefore avoids the mess you find in C++ programs where every programmer has their own private conventions which can lead to confusion and useless debate. However it still seems to me that the case distinction, at least on the level of type constructors, becomes problematic and possibly inconsistent especially if I consider the effects of trying to incorporate something like the ML module system as well as type classes. (For example the Moby language (http://moby.cs.uchicago.edu/ ), a possible successor to SML, uses capitalization for type constructors similar to Haskell which means that type parameters in functor applications must be uppercase, which conflicts with the use of lowercase type params for classes which are a special kind of functor... (Moby itself doesn't encounter any difficulty since it doesn't have type classes)). Best regards, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Module system, was Re: GHC source code improvement ideas
Johannes Waldmann wrote: Brian Hulley wrote: In the long term, Haskell needs a better module system IMHO [...] I agree with the symptoms that were described, but I draw a different conclusion. We don't need to change the language - we need better tools (IDEs) that operate not at the textual level, but use the annotated syntax tree, including knowledge on fully qualified names and types. Hi Johannes, I agree that better tools would be a good thing, and could improve the programming experience considerably, but I still think that an improved module system design would be an orthogonal benefit. Best regards, Brian. ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Module system, was Re: GHC source code improvement ideas
Ian Lynagh wrote: On Fri, Jan 04, 2008 at 08:34:22AM +, Simon Peyton-Jones wrote: | 4. A more radical change would be introducing hierarchical modules. It's a pity that GHC.* is already used in base. I'm not sure what the best thing to do is in the short term. How about Language.Haskell.Compiler.GHC.* In the long term, Haskell needs a better module system IMHO, since the problem at the moment is that having to write the full hierarchical name in each module means that you need to know in advance, before you've even started writing a program, where each module will fit into the global namespace, which makes it extraordinarily difficult to do exploratory programming or bottom-up development, and the need to write so many import directives in each module makes it extremely painful not to mention overly hard-wired. A good direction IMHO is the way SML structures are grouped using CM.make (SML/NJ) or MLBasis (MLton and others), so that there are no import directives at all: a separate group definition determines what is in scope, and compilation proceeds by chasing these group definition files rather than chasing modules. Translating this into Haskell, the module syntax could be simplified and other modules could be nested and aliased within a module, so that it is easy to create different hierarchical views of the modules which are in scope to suit the particular module being written or clients of that module: -- Leaf.hs module Leaf where module String where open Data.ByteString.Char8 type T = ByteString module Map = Data.Map module Util where foo :: Int - Int foo i = i --Other.hs module Other where bar :: Int - Leaf.String.T bar = Leaf.String.pack . show . Leaf.Util.foo Note that here there is no need for any import directives, since the modules which are in scope when Leaf.hs is compiled would be determined by whatever group Leaf.hs is part of (with respect to that particular program), which would be defined in a separate file: --MyBasis.hsg local $Haskell/StdBase.hsg Leaf.hs Other.hs Within the .hsg files, groups and modules are referenced by filename, and is just a simple list of components that are required and/or exported by the group. In the .hsg file above, MyBasis will export the contents of Leaf.hs and Other.hs, which are compiled in an environment augmented by StdBase (which is not itself exported by MyBasis). (See CM.make and the MLBasis system for more details - in particular, for any given program a module may appear in only one group, but the same module may appear in different groups in different programs thus facilitating easy exploratory programming and re-organization without breaking previous programs.) This can be taken further to get an even more powerful system by using parameterized traits and explicit instantiation for modules: trait T a b where foo :: a - b bar :: Int - Int bar i = i + 1 module M where include T Int String foo = show . bar Here, the body of a module is always a trait, and the above is equivalent to: trait T a b = tra foo :: a - b bar :: Int - Int bar i = i + 1 module M = new tra include T Int String foo = show . bar which makes it more explicit that conversion of the contents to actual code (ie linking, allocation/identity/initialization of CAFs and foreign objects, generativity of data types etc) happens only in the module decl. The great thing about making instantiation explicit is that traits are pure functional values and so can easily be combined with no side effects, whereas modules may in general contain mutable state eg to interface with some external C library and thus are objects-with-identity. Thus the separation solves the whole problem of applicative vs generative functors in ML, as well as solving the problem of mutually recursive structures (functors become a redundant concept because you can always start with including a trait then overriding some decls with more instantiated (here used in a different sense) decls and/or traits). Last but not least, a trait could also be used similarly to a signature, except that definitions in the trait can be considered to be default implementations. Therefore in this scenario the body of a class or instance decl is just a trait and so could be composed using other traits etc. (Each instance decl instantiates the trait given in the body merged with the trait given in the class leading to a possibly parameterized module.) Anyway these are some of the directions I am currently working on for my new
Re: Module system, was Re: GHC source code improvement ideas
Brian Hulley wrote: Ian Lynagh wrote: On Fri, Jan 04, 2008 at 08:34:22AM +, Simon Peyton-Jones wrote: | 4. A more radical change would be introducing hierarchical modules. Sorry I quoted what Simon PJ replied to not what he wrote so I should have written: Ian Lynagh wrote: On Fri, Jan 04, 2008, Twan van Laarhoven wrote: 4. A more radical change would be introducing hierarchical modules. Though this is again not quite right since Ian did not write line 3... Apologies to Simon PJ and Twan (and now also to Ian) for mis-quoting ;-) Brian. ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: [Haskell-cafe] Dynamic choice of reverse implementation
Krzysztof Kościuszkiewicz wrote: Fellow Haskellers, I wanted to experiment a bit with lists and sequences (as in Data.List and Data.Sequence), and I got stuck. I wanted to dynamically select processing function depending on cmdline argument: main = do args - getArgs let reversor = case args of [sequence] - reverseList [list] - reverseSeq _ - error bad args input - getContents let output = reversor $ lines $ input mapM_ putStrLn output In my oppinion reversor would have type reversor :: (Foldable f) = [a] - f b No, this is the wrong type. To find the correct type, if you look at the type of the input argument in your code it will be the result of (lines), so from ghci: Prelude :t lines lines :: String - [String] Prelude Therefore (reverseor) has type [String] - ??? Now for the output type, you are using (output) as an input to (mapM_ putStrLn). (mapM_) takes a list and uses its argument to do something to each element of the list. So, since the input to (putStrLn) is (String), the input to (mapM_ putStrLn) is ([String]). Therefore reversor :: [String] - [String] So reverseList is just Data.List.reverse as you've got it (though presumably you meant to write [list] - reverseList and not reverseSeq). For using Data.Sequence to implement reversor, all you need to do is first convert [String] to Seq String, reverse the sequence, then convert back from Seq String to [String]. Hope this helps, Brian. but I couldn't get this to work. I've tried typeclass approach: class (Foldable f) = Reversor f where reverse' :: [a] - f a instance Reversor ([]) where reverse' = Data.List.reverse instance Reversor ViewR where reverse' = viewr . foldr (|) empty reverseList = reverse' :: (???) reverseSeq = reverse' :: (???) but now in order to differentiate between reverse' functions I'd have to provide different type annotations, and then reversor won't typecheck... Similar problem surfaced with this try: data Proc = SP | LP reverseList = reverse' LP reverseSeq = reverse' SP reverse' :: (Foldable f) = Proc - [a] - f a reverse' LP = Data.List.reverse reverse' SP = viewr . foldr (|) empty So now I'm looking for some suggestions how should I approach the problem... Regards, ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Dynamic choice of reverse implementation
Brian Hulley wrote: Krzysztof Kościuszkiewicz wrote: So the type of mapM_ used in the code is (Foldable t, Monad m) = (a - m b) - t a - m () I'd like to keep the generic Foldable t there when m is specialized to IO. I thought this would allow type of reversor to be specialized to (Foldable f) = [String] - f String ... I'd like to avoid [a] - something - [a] Yes this type should be fine. I should have said though that in your code, because one arm of the case construct returns Data.List.reverse, the type of reversor is fixed to [a] - [a]. The other arm of the case construct could make use of a more general function eg reverseFoldable :: (Foldable f, Foldable g) = f a - g a but it would only be used at f == [], g == []. So in terms of the command line test harness, I think the only way is to explicitly choose the foldable you want to try out eg by using (Foldable.toList . Seq.reverse . Seq.fromList) etc. An alternative might be to just write some different implementations of reverse functions in a module then load the module into ghci to test them out interactively so their types don't get unified with each other. Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Dynamic choice of reverse implementation
Krzysztof Kościuszkiewicz wrote: So the type of mapM_ used in the code is (Foldable t, Monad m) = (a - m b) - t a - m () I'd like to keep the generic Foldable t there when m is specialized to IO. I thought this would allow type of reversor to be specialized to (Foldable f) = [String] - f String ... I'd like to avoid [a] - something - [a] Yes this type should be fine. To implement reversor though you'd still need to first convert from the concrete list to whatever foldable you're using, before reversing the foldable, or implement something more general eg: reversor :: (Foldable f, Foldable g) :: f a - g a Of course with lazy evaluation + compiler optimizations the lists in [a] - something - [a] should be erased at compile time... ;-) Regards, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Desugaring of infix operators is (always?) the wrong way round
Sam Hughes wrote: Brian Hulley wrote: ... For example, with the prefix definition of a function with multiple clauses, the function name at the start of each clause is already lined up since it must appear at the margin of the current layout block ... Or you could have everything be backwards, and use an editor that right aligns things. (a - b) - [a] - [b] :: map [] = [] _ map x f : xs f map = (x:xs) f map There is still a reversal here between the order of arguments in the type signature and the order in the clauses. Henning Thielemann wrote: Curried functions like f :: a - b - c suggest a swapped order of arguments for (-), since 'f' must be called this way b a f Maybe it should be f :: c - b - a Which would fix this reversal. However there are 2 other kinds of reversal with postfix notation: 1) Declarations start with a keyword followed by some content whereas function definitions start with the args followed by the function name 2) Special constructs like case or let have to start with the keyword (so the parser knows what kind of thing it is supposed to parse next and so that the editor knows how to highlight what the user is typing before the user has finished typing the whole construct), again making a reversal between built-in constructs and constructs you can define using higher order functions (eg consider if as a user-defined construct in a postfix language) I've come to the conclusion that whereas postfix notation is extremely neat for simple stack-based languages like Forth and PostScript it would not play well with languages which have a structured syntax since structured syntax + left to right reading order implies each syntactic element must start with a head followed by content appropriate to that element, or else recursive descent parsing and/or as-you-type grammatical highlighting would be impossible, and therefore in terms of function application, the head must of course be the function itself hence Prefix is the only solution. Jonathan's comparison to natural languages made me think of it this way: x `plus` y === [Subject] [Verb] [Object] x .plus(y) === [Subject] [Verb Object] plus y x === [Verb Object] [Subject] plus x y === [Verb Subject] [Object] which illustrates why infix notation feels natural (corresponds to SVO in English etc), why OOP notation feels natural, why prefix notation is natural for a functional language (since we are interested primarily in the transformation not the things being transformed hence we put [VO] first), and why the desuraging of infix in Haskell/ML is quite simply just wrong, since the object is now separated from the verb. ok wrote: Binary operators have two arguments. That's why sections are needed. What's wrong with just using (flip)? I am a bear of very little brain, and I would find it VERY confusing if the order of arguments in an operator application did not match the order of arguments in a function call. I can live with x @ y = (op @)(x, y)(* SML *) x @ y = (@) x y-- Haskell but making the orders different would guarantee that I would *always* be in a muddle about which argument was which. Living with inconvenient argument orders is vastly easier than with inconsistent ones. If you inwardly parse x @ y as [x] [@ y] then the prefix notation is naturally formed just by putting the specialized verb before the subject instead of after it ie [@ y] [x]. Therefore I think this desugaring, though different from the usual one, would seem natural as soon as the reason for it was understood (of course, only if you agree with the reason ;-) ), and the great advantage of it is that we could write library functions without having to decide in advance whether or not they should be used with infix sugar. (Regarding Henning's point about ((-) a) being needed for Reader monads we could define type Fun a b = a - b and then use (Fun a)) In any case, thanks to all who replied. I've found the discussion very illuminating and it's certainly helped a lot to clarify the issues for me, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Desugaring of infix operators is (always?) the wrong way round
Hi, I'm in the process of designing a little language inspired by Haskell but imperative, and have hit an issue regarding infix syntax which may be of interest also to anyone thinking about future revisions of Haskell or the problem of consistent parameter order in libraries. I'm wondering if anyone can shed light on the reason why x # y gets desugared to (#) x y and not (#) y x since the first desugaring always seems to lead to (#) having to be defined in a way that is unnatural for functional programming. This is why a lot of functions in the standard libraries have their arguments the wrong way round. For example in Data.Bits we have: shiftL :: a - Int - a whereas the natural argument order for a functional language would be to make it so that in an application one has the verb first followed by the noun as in: shiftL' :: Int - a - a so we could write (shiftL' 3) to denote the operation of shifting something left by 3 eg: let shiftLeftByThree = shiftL' 3 in map shiftLeftByThree [10, 78, 99, 102] (This choice of argument order is explained at http://www.haskell.org/haskellwiki/Parameter_order ) Similarly, considering arithmetic, it would make a lot more sense to me to define: x - y === (-) y x since the action here is take away y and the noun is x so the natural functional reading of (-) a b is subtract a from b. To be consistent this would also have to apply to the use of (-) in types to get: a - b === (-) b a Can anyone think of an example where the current desugaring of infix arguments gives the correct order when the function is used in a postfix application? (apart from commutative functions of course!) Thanks, Brian ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Desugaring of infix operators is (always?) the wrong way round
Brian Hulley wrote: I'm wondering if anyone can shed light on the reason why x # y gets desugared to (#) x y and not (#) y x Can anyone think of an example where the current desugaring of infix arguments gives the correct order when the function is used in a postfix application? (apart from commutative functions of course!) Sorry I meant to write *prefix* application ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Desugaring of infix operators is (always?) the wrong way round
Jonathan Cast wrote: On Tue, 2007-09-25 at 19:18 +0100, Brian Hulley wrote: Brian Hulley wrote: I'm wondering if anyone can shed light on the reason why x # y gets desugared to (#) x y and not (#) y x Of course, this is all a consequence of the well-known failure of natural language: verbs come before their objects. It is thus natural to write f(x), when in fact it is the object that should come first, not the function. Switching to a (natural) language where (finite) verbs come at the end of sentences, where they belong, should fix this issue in time. Doing the same in a functional language would be ideal as well, but might limit its use among those who speak inferior natural languages. Thanks, I must look into using postfix notation. It's used in Forth and Postscript and I seem to dimly recall that there is a natural language somewhere that also uses it but I can't remember which one. Not only would it solve the infix/prefix dilemma, but it would also be consistent with a sugar for an object oriented syntax for application: a b c f a .f(b, c) (Using a dot glued on its right and a left paren glued left to avoid ambiguity with unglued dot (function composition) and unglued left paren (unit/tuple/bracketing)) It's not so clear to me what the syntax for types should be in a postfix language. Also, a problem might be that it is not so easy to use the multiple-clause style of function definition eg compare: map _ [] = [] map f (h : t) = f h : map f t with [] f map = [] (h : t) f map = h f : t f map since the function name is no longer conveniently at the margin of whatever layout block we are in so extra efforts would need to be made to line them up, though this is a minor issue. Thanks again, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Desugaring of infix operators is (always?) the wrong way round
Ryan Ingram wrote: My comments inlined below... On 9/25/07, Brian Hulley [EMAIL PROTECTED] wrote: let shiftLeftByThree = shiftL' 3 in map shiftLeftByThree [10, 78, 99, 102] let shiftLeftByThree = (`shiftL` 3) in ... Aha! but this is using section syntax which is yet another complication. Hypothesis: section syntax would not be needed if the desugaring order was reversed. Can anyone think of an example where the current desugaring of infix arguments gives the correct order when the function is used in a postfix application? (apart from commutative functions of course!) A couple off the top of my head: (:) :: a - [a] - [a] Yes that's one that had totally slipped my mind ;-) | :: MonadPlus m = m a - m a - m a (how do you define correct in this case, anyways?) I'm not so sure about this one eg: first | second (trychoice second) first because (trychoice second) encapsulates what to do when its argument action fails. Even for shift I can think of several reasons to want to use it both ways; for example, unpacking a bitfield from a Word16: unpack v = (getM 0 255, getM 8 1, getM 9 31, getM 14 3) where getM = (..) . (shiftR v) I suppose with some ops perhaps there is no most common way of wanting to use them and hence no one-true-way argument order for those ops. Thanks for the examples, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Desugaring of infix operators is (always?) the wrong way round
Dan Piponi wrote: On 9/25/07, Brian Hulley [EMAIL PROTECTED] wrote: ..I seem to dimly recall that there is a natural language somewhere that also uses it but I can't remember which one. Every permutation of [S,V,O] appears in 'nature': http://en.wikipedia.org/wiki/Word_order. Thanks for the link - I see [Subject, Object, Verb] is actually the most common word order. Also, a problem might be that it is not so easy to use the multiple-clause style of function definition I disagree, it's easier with postfix functions. With prefix functions, to get line-up you insert space in the middle of the line. With postfix notation you would often insert space at the beginning of a line, a much easier place to insert text, because there is a keystroke, in most text editors, to take you to the beginning of a line. I don't understand what you mean. For example, with the prefix definition of a function with multiple clauses, the function name at the start of each clause is already lined up since it must appear at the margin of the current layout block (especially if you follow the simple rule of always following a layout starter token by a newline rather than starting a new multi-line layout block in the middle of a line), whereas with the postfix notation you'd need to manually line up the function names if you wanted the same neat look. It's not so clear to me what the syntax for types should be in a postfix language. Postfix, of course! So you'd write data a Tree = Leaf | a a Tree Sorry I meant what should the syntax of type declarations for functions be? For example, with prefix map (writing lists without sugar for clarity) we have: map :: (a - b) - List a - List b map _ Empty = Empty map f (PushF h t) = PushF (f h) (map f t) The occurrence of map in the type decl lines up with the 2 occurrences of map in the clauses, and the types of the arguments are in the same order in the type as in the patterns in the clauses. A postfix version could be: map :: (a - b) - a List - b List Empty _ map = Empty (h t PushF) f map = (h f) (t f map) PushF but now the occurrences of map no longer line up and the argument order is reversed between the type and the value syntax. Of course the problem disappears if you just discard multiple clause syntax and use: (list :: a List) (f :: a - b) map :: b List = case list of Empty - Empty h t PushF - (h f) (t f map) PushF Confusingly, ocaml does something like this, with postfix notation for types and prefix notation for function application. I've never understood why {Oca, S}ML's creators decided to make life so difficult and confusing by introducing an arbitrary reversal between type and value syntax. ;-) Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Status of GHC runtime dependency on GNU multi precision arithmetic library
Stefan O'Rear wrote: On Wed, Aug 15, 2007 at 06:41:53PM +0100, Brian Hulley wrote: ... I was wondering if there are any plans to remove the GNU mp library from the runtime ... http://hackage.haskell.org/trac/ghc/wiki/ReplacingGMPNotes Thanks for the link. ... although the program includes code that is libre/gratis free the program is not itself free etc etc... Huh? ... I meant if you are distributing a proprietary program then you have the problem of trying to explain to an end-user all the intricacies involved with the LGPL without conveying the impression that the whole program is free. My impression is that someone who doesn't know anything about programming might have a hard time understanding the LGPL correctly. Ian Lynagh wrote: I'll be looking at making it optional once 6.8.1 is out of the way, but you will need to use a GHC compiled with an alternative; you won't be able to make a non-GMP program with a GMP GHC. Thanks, that's good news. Perhaps one option for the non-GMP version of GHC would be to have a large integer library written in Haskell itself, since it is useful to have large integers even if they are not as fast as those provided by GMP (eg when writing a lexer it is useful to have large integers to correctly lex integer literals (ie without silently truncating them to the capacity of an Int) but speed here is not that important). To get high speed for stuff in external libs, perhaps some way of extending the foreign interface to allow direct access to the Haskell heap instead of always having to copy via the C heap, would be useful. Duncan Coutts wrote: Sounds to me like the simlest solution for you would be if GHC could use a dynamically linked gmp.dll on Windows. That also sounds like much less work that replacing gmp completely. This would certainly make things easier though it doesn't solve every problem. For example, the LGPL requires you to give permission to people to reverse engineer your application, in order for them to be able to understand it enough to get it to work with an updated version of the LGPL component. Although this is perfectly reasonable imho, it leaves me with a problem if my application also needs to make use of eg Microsoft runtime components or third party proprietary statically linked libraries since there are parts of my program binary for which I do not have the authority to grant permission to reverse engineer thus it may not even be possible for me to comply with the terms of the LGPL. Of course I am not a lawyer so I may have got this wrong, but since I can't possibly afford to hire a lawyer to look into all of this I have to play it safe and therefore would prefer to avoid any use of LGPL components in a proprietary app. Thanks also to everyone else who replied, Brian. ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Status of GHC runtime dependency on GNU multi precision arithmetic library
Duncan Coutts wrote: On Thu, 2007-08-16 at 14:22 +0100, Brian Hulley wrote: .. For example, the LGPL requires you to give permission to people to reverse engineer your application... thus it may not even be possible for me to comply with the terms of the LGPL. From the LGPL v3: You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: [list of stuff you have to do] So it looks like you only have not restrict reverse engineering for the purposes of making updated GMP libs work with your program. Since the MS Runtime components do not interact directly with the GMP at all you shouldn't need to grant users the right to reverse engineer those components. Indeed it's only ghc library and rts code that would interact with gmp.dll. Thanks for suggesting that. It sounds reasonable though I tend to get a bit paranoid when it comes to legal things - will the FSF agree with the above interpretation etc. BTW, I don't think it should be too hard to construct a notice that indicates that portions of the work are covered by specific copyright licences, the details of which are available. After all Microsoft have dozens of these notices for various bits of BSD code they use and nobody mistakes Windows for Free software. True, but if there's any chance of just getting rid of the GMP altogether from a version of GHC there would be no tricky issues when it comes to distributing proprietary apps, thus potentially increasing GHC's user base, making Haskell more popular, and hopefully leading to more BSD3 libs being written by those new users... ;-) Best regards, Brian. ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Status of GHC runtime dependency on GNU multi precision arithmetic library
Hi, I know this is a sensitive issue and I absolutely don't want to start any kind of discussion about the merits or otherwise of LGPL, but I was wondering if there are any plans to remove the GNU mp library from the runtime so that it would be possible to distribute native executables compiled with GHC without having to deal with the additional issues raised by the current inclusion of this LGPL component in the runtime. (Afaik everything else in ghc is under a BSD3 license.) It's less of an issue on Linux where libgmp is dynamically linked but when thinking about using Haskell ghc for creating Windows apps it is for me a real problem, because it would mean I'd have to distribute the code for my app as a library along with the code as an executable, thus doubling the download size for my apps as well as having to include a license that has to explain to a possibly non-technical user that although the program includes code that is libre/gratis free the program is not itself free etc etc... Regards, Brian. ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
[Haskell-cafe] Syntax for lambda case proposal could be \of
Hi, On http://hackage.haskell.org/trac/haskell-prime/wiki/LambdaCase the proposed syntax for lambda case is: case of alts but this has a really bad downside for interactive editors: it doesn't allow one to distinguish between an incomplete construct and a completed construct thus removing one opportunity for an editor to alert the user (eg by highlighting) that there is something missing in the program text. Therefore I propose: \of alts which doesn't suffer this problem since the keyword of can never follow a '\' in the existing grammar. However I can't edit the H' wiki, so if anyone agrees that the above syntax is better please could they add the above to the page. Thanks, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Syntax for lambda case proposal could be \of
Stefan O'Rear wrote: On Wed, Aug 15, 2007 at 06:58:40PM +0100, Duncan Coutts wrote: On Wed, 2007-08-15 at 10:50 -0700, Stefan O'Rear wrote: OTOH, your proposal provides (IMO) much more natural syntax for multi-pattern anonymous functions, especially if we stipulate that unlike a case (but like a lambda) you can have multiple arguments; then you could write stuff like: sumTo0 = foldr (\of 0 k - 0 n k - n + k) 0 sumTo0 = foldr (\0 k - 0 n k - n + k) 0 foo = getSomethingCPS $ \ arg - moreStuff is now a syntax error (\ { varid - } matches no productions). A multi-way lambda could be introduced using \\ thus: sumTo0 = foldr (\\ 0 k - 0; n k - n + k) 0 [from a previous post] It's not like the current language has that property; consider (map myFunction) - is that an error or a partial application? By construct I meant only those grammatical elements involving keywords, and was thinking about situations where you might for example have various syntax templates bound to function keys eg in Haskell the following are incomplete: case of if then else data where deriving (let in could still be marked as incomplete even if it is ok according to the grammar since it would be weird to bother writing a let with no bindings.) There is a similar problem with the way template haskell uses unmatched quotes such as 'a so it's no longer possible to determine whether this should be marked as an incomplete character literal or a complete TH name. I suppose my main point is that it's useful for a syntax to have plenty of unfilled gaps that result in an error when written rather than filling all those gaps with different meanings... Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Language support for imperative code. Was: Re: monad subexpressions
Brian Hulley wrote: apfelmus wrote: Brian Hulley schrieb: main = do buffer - createBuffer edit1 - createEdit buffer edit2 - createEdit buffer splitter - createSplitter (wrapWidget edit1) (wrapWidget edit2) runMessageLoopWith splitter ... Thus the ability to abstract mutable state gives to my mind by far the best solution. I'm not sure whether mutable state is the real goodie here. I think it's the ability to indpendently access parts of a compound state. http://www.st.cs.ru.nl/papers/2005/eves2005-FFormsIFL04.pdf This is indeed a real key to the problem. Of course this is only one aspect of the problem... Thinking about this a bit more, and just so this thought is recorded for posterity (!) and for the benefit of anyone now or in a few hundred years time, trying to solve Fermat's last GUI, the object oriented solution allows the buffer object to do anything it wants, so that it could negotiate a network connection and implement the interface based on a shared network buffer for example, without needing any changes to the client code above, so a functional gui would need to have the same flexibility to compete with the OO solution. Another thing that would be interesting would be to have a formal treatment of what is supposed to happen in a gui. For example, when you move the mouse over a control which has become dirty (ie needs to be re-rendered because its state is now inconsistent), what should the control do? Should it respond as if the new state were already visible to the user, or should it interpret the mouse position according to the last state that was rendered, or should it just ignore all mouse events until the next time it gets rendered? This is not a trivial question because you could imagine an animated control where the user might naturally be following the movement, whereas when the user clicks on a cell in a spreadsheet when the cells to the left have now expanded due to a change in data thus moving the cell along (but where this updated model has not yet been re-rendered) the user might be irritated at the wrong cell being selected... It's tricky little issues like this that I haven't found any documentation for anywhere, and which would make a proper mathematical treatment of interaction with a gui very useful, regardless of whether it is implemented in OOP or functional style. Anyway just a thought, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Language support for imperative code. Was: Re: monad subexpressions
apfelmus wrote: Brian Hulley schrieb: main = do buffer - createBuffer edit1 - createEdit buffer edit2 - createEdit buffer splitter - createSplitter (wrapWidget edit1) (wrapWidget edit2) runMessageLoopWith splitter ... Thus the ability to abstract mutable state gives to my mind by far the best solution. I'm not sure whether mutable state is the real goodie here. I think it's the ability to indpendently access parts of a compound state. In other words, the IORef created by buffer is a part of the total program state but you can access it independently. There is a functional idiom for that, see also Sander Evers, Peter Achten, and Jan Kuper. A Functional Programming Technique for Forms in Graphical User Interfaces. http://www.st.cs.ru.nl/papers/2005/eves2005-FFormsIFL04.pdf Thanks for this reference. This is indeed a real key to the problem. (Though a possible downside with compositional references might be efficiency as the modified sub-state needs to be injected back into a new composite state but perhaps the solution here would be to have uniqueness typing as in Clean so that these injections could hopefully be erased at compile time.) I think one of the issues with Haskell is that there are so many features to choose from it is difficult to know how to approach a problem eg for streams you can have 1) A lazy list 2) A typeclass with get and pushBack methods 3) An object using an existential to wrap (2) 4) A record containing get and pushBack methods 5) A monad with get and pushBack actions 6) A simple function wrapped in a newtype: newtype Stream a = Stream (() - Maybe (a, Stream a)) and I tend to only discover a simple solution like (6) (which works equally well for both strict and lazy languages) after spending an enormous amount of time on 1,2,3,4,5... ;-) - For Graphics, I want to build a graphic from smaller ones and then draw it. I don't want to know how drawing is implemented and what mutable state might be involved. - For a GUI, I want to write down the data dependencies and a library converts this to a mesh of mutable state. That's what I mean with higher level functional model. I agree this would be ideal. A challenge I don't yet know how to solve, when dealing with 3d graphics, is that it seems that for efficiency it is necessary to consider a mesh of triangles to be an object with identity in order to be able to display an updated mesh (eg as the user drags a vertex with the mouse) in real time. This is because the representation of a mesh is constrained by the low level details of the graphics system eg vertices might need to be represented by a contiguous array of unboxed positions and normals, and triangles by a contiguous array of vertex indices, and it is too expensive to copy these arrays on each frame. Perhaps though this is another case where some form of uniqueness typing as in Clean could come to the rescue so one could write: createMesh :: [Vertex] - [[VertIndex]] - Mesh moveVertex :: Vertex - *Mesh - *Mesh instead of createMesh :: [Vertex] - [[VertIndex]] - IO Mesh moveVertex :: Vertex - Mesh - IO () Best regards, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Language support for imperative code. Was: Re: monad subexpressions
apfelmus wrote: However, most genuinely imperative things are often just a building block for a higher level functional model. The ByteString library is a good example: the interface is purely functional, the internals are explicit memory control. It's a bad idea to let the internal memory control leak out and pollute an otherwise purely functional program with IO-types. Hi Apfelmus, This is a really interesting discussion that touches on issues I'm currently working with (I'm designing a strict version of Haskell to explore various ideas about modules, namespace management, and how to get really efficient machine code but without losing the convenience of accurate garbage collection etc, but I'm having difficulties deciding between the monadic path and the impure path), so I've forked this new thread. Regarding the quote above, if the API must hide explicit memory control from the user the only way I can see of doing this would be to use (unsafePerformIO), which really is unsafe since Haskell relies on the fact that mutable operations can't escape from the IO monad in order to get away with not having to impose a value restriction as in ML. If you don't use (unsafePerformIO), then the slightest need for mutable data structures pollutes the entire interface. For example in the excellent paper you quoted N. Ramsey and J. Dias. An Applicative Control-Flow Graph Based on Huet's Zipper http://www.eecs.harvard.edu/~nr/pubs/zipcfg-abstract.html http://www.eecs.harvard.edu/%7Enr/pubs/zipcfg-abstract.html the authors are pleased to have found an Applicative solution, and indeed their solution has many useful and instructive aspects. However on page 111, hidden away in the definition of their API function to create a label, is a call to (ref 0) ;-) The equivalent implementation in Haskell would completely destroy all hope of using this in a pure context and force all use of the API into the IO monad. Haskell and ML seem to stand at opposite poles. Haskell is designed so that any attempt at abstracting mutable local state will infect the entire program (modulo use of a highly dangerous function whose semantics is entirely unclear, depending on the vagaries of evaluation strategy of the particular compiler) whereas people have been struggling in the ML community for at least 15 years to try and find a way to hide the fact that mutable storage is being used (cf attempts to find a proper solution to the unsoundness introduced by polymorphism and ref without having to use imperative/weak type variables etc). Meanwhile, C++, C#, and Java programmers get a type system (thinking only about static methods using generics/templates) that seems to me no less powerful than that of the prenex polymorphism of ML, yet without any of the unsoundness problems, and therefore without the need of a value restriction (afaiu this is because their template/generic definitions stand in for an infinite family of monomorphic bindings instead of ML which tries unsuccessfully to make one piece of memory represent each element of an infinite family of values simultaneously). Not only this, but there seems to me to be many problems for which it is natural to think in terms of objects with identity and mutable state. I can readily discard the concepts of deep inheritance hierarchies and open recursion but this still leaves the problem of identity and localised mutability. For example consider a simple GUI with 2 edit widgets, a splitter, and a single buffer that contains the text being edited. The idea is that you should be able to use either edit widget to interact with the same buffer eg to edit at different locations in the buffer. A simple imperative solution might be something like: main = do buffer - createBuffer edit1 - createEdit buffer edit2 - createEdit buffer splitter - createSplitter (wrapWidget edit1) (wrapWidget edit2) runMessageLoopWith splitter Here it's really clear what's happening, and different objects in the program correspond exactly to how I think about what I'm trying to do ie I want to create individual objects with identity and then plug them together. I don't want to have to bother about passing state around, or having to define a new data type every time I want a different configuration of widgets. Thus the ability to abstract mutable state gives to my mind by far the best solution. In contrast, all the pure functional GUIs that I've seen are just wrappers around someone else's imperative code, and moreover, they exchange the simplicity of the object oriented imperative API for a veritable mindstorm of unbelievably heavy, clunky, slow, inefficient, inextensible, hard to understand encodings that seem to me to have the effect of turning a high level language into some kind of circuit board (I'm thinking of arrows etc). Indeed everyone seems to be using either WxWidgets or
Re: [Haskell-cafe] Language support for imperative code. Was: Re: monad subexpressions
Martin Percossi wrote: Brian Hulley wrote: hidden away in the definition of their API function to create a label, is a call to (ref 0) ;-) The equivalent implementation in Haskell would completely destroy all hope of using this in a pure context and force all use of the API into the IO monad. Really? I would have thought this is a job for the ST monad, in which case the API can be wrapped up in a runST or similar; no need for leaking IO monads. Or am I missing something? Well I agree you're right on this particular use of a Ref, since their program is only dealing with a mapping from input to output so once they're finished using the data structure there is no longer any need for the ref and so the result can be returned to the rest of the program. However there are 2 problems with this approach in general afaics: 1) All code that uses this data structure ie that participates in the implementation of the transformations by using the API functions will have to be in a monad (ST or IO, it really doesn't matter in terms of all the perceived burdensomeness of do notation relative to normal applicative code). 2) The example doesn't transfer to an interactive situation, where we would need to keep the data structure around and use it forever - because we would be forever trapped inside the ST monad otherwise we'd lose that particular STRef which we were hoping to use to efficiently update the output in the face of a delta in the input. Corey - I found this page helpful to get an understanding of the value restriction in ML: http://www.smlnj.org/doc/Conversion/types.html The restriction was proposed by Andrew Wright in 1995: Simple Imperative Polymorphism by Wright http://citeseer.ist.psu.edu/wright95simple.html Some other related papers are: The Type and effect discipline by Talpin and Jouvelot 1992 Standard ML-NJ weak polymorphism and imperative constructs by Hoang, Mitchell, and Viswanathan Weak polymorphism can be sound by Greiner 1993 and more recently (2003) Relaxing the value restriction by Garrigue http://citeseer.ist.psu.edu/garrigue03relaxing.html (Note that even now there is still no real solution to it.) Best regards, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Language support for imperative code. Was: Re: monad subexpressions
Hugh Perkins wrote: On 8/8/07, *Brian Hulley* [EMAIL PROTECTED] mailto:[EMAIL PROTECTED] wrote: In contrast, all the pure functional GUIs that I've seen... In defense of Haskell (wow!), note that imperative languages are not without problems in GUIs. In a multithreaded environment, If you're using multiple threads you'd need to be in the IO monad to create/manipulate the MVars or TVars or whatever. (In contrast to eg AliceML where you could easily use a synchronising logic variable without having to leave all the familiar applicative coding comforts behind to brave the fiercesome lonely toil of Monadia ;-)) typically only one thread is allowed to manage the GUI, and then you typically need to set up some sort of message-passing system to communicate between this thread and the others AFAIK? This is a total PITA, so if someone has a solution for this that would rock :-) Question: to what extent do the Haskell wrappers around gtk and wxWidgets suffer from this problem? I mean, I havent tried them, so it's a genuine question. I don't know though I seem to recall some info on this on the website of Gtk2Hs. (Note: off the top of my head, in an imperative language, I guess one could use some sort of generator to take an interface and generate the message classes, and marshalling classes automatically) (Disclaimer: I havent really searched very hard for ways to handle threading in GUIs in imperative languages, since mostly I either use web pages as the visual interface, which avoids around the problem, or use a single thread, which also avoids the problem) So far I've always managed to get away with just using a single threaded GUI. I think you run into problems with XLib and OpenGL (on GNU/Linux at least) if you try to call into those APIs from multiple threads and also it seems better to separate concerns by having all rendering code, including cacheing of geometry etc, in the same thread since it's easy enough to spawn new threads to do calculations and set a flag in the relevant widget when the result is complete... Best regards, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] a regressive view of support for imperative programming in Haskell
Paul Hudak wrote: All of the recent talk of support for imperative programming in Haskell makes me really nervous ... if we give imperative programmers the tools to do all the things they are used to doing in C++, then we will be depriving them of the joys of programming in the Functional Way. How many times have we seen responses to newbie posts along the lines of, That's how you'd do it in C++, but in Haskell here's a better way Perhaps I may have sounded unappreciative of all the hard work that's been done trying to find solutions to the problem of GUI programming in a pure functional style. I think the problem is that for the purposes of research, it is sufficient to show that a concept can be implemented but the speed of the resulting program is not that important compared to the essential ideas. Thus the concept of a GUI as a time varying continuous function of events and response pictures (represented as functions:: Vector3 Float - RGB) is tremendously appealing, and will surely become the standard way when machines get fast enough, but for the moment this nice pure functional way just doesn't seem directly applicable (;-)). I see the problem you're pointing to though - that the language could become caught in the middle trying to serve two rather different purposes namely a pure ground for research and a fast general purpose platform for creating programs now. As for me, the issue is just that after spending almost 2 years with Haskell trying to find/discover a purely functional solution to this problem that will be suitable for a practical high speed graphics application on standard hardware, being unsuccessful, and not having any funding to pursue this research further, my only option is to either use the imperative monadic style of Haskell programming or to use OCaml or C++, because I need to get something written right now that I can put on my website to sell... Personally I don't find the existing do notation all that burdensome - I've got used to it, and even though each action must be explicitly written, the ease with which higher order functions can be introduced to factor out commonality means that the do blocks are often shorter than the corresponding C++ code from my previous GUI. Furthermore, even though I'm using the imperative style, the use of Haskell has led me to surprisingly neat solutions to several problems that I didn't discover when I implemented the previous versions in C++ and C#, so I think there are still great benefits to be had from using Haskell or languages inspired by it. Best regards, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Newbie question: multi-methods in Haskell
peterv wrote: In de book Modern C++ design, Andrei Alexandrescu writes that Haskell supports “multi-methods” Using multi-methods, I could write (in pseudo code) collide (Asteroid, Planet) = an asteroid hit a planet collide (Asteroid, Earth) = the end of the dinos ... collide (Planet, Asteroid) = collide (Asteroid, Planet) collide (Earth, Asteroid) = collide (Earth, Asteroid) Hi, In Haskell you can use multi parameter type classes to solve this problem: {-# OPTIONS_GHC -fglasgow-exts -fallow-undecidable-instances -fallow-overlapping-instances #-} module Collide where class Collide a b where collide :: (a,b) - String data Solid = Solid data Asteroid = Asteroid data Planet = Planet data Jupiter = Jupiter data Earth = Earth instance Collide Asteroid Planet where collide (Asteroid, Planet) = an asteroid hit a planet instance Collide Asteroid Earth where collide (Asteroid, Earth) = the end of the dinos -- Needs overlapping and undecidable instances instance Collide a b = Collide b a where collide (a,b) = collide (b, a) -- ghci output *Collide collide (Asteroid, Earth) the end of the dinos *Collide collide (Earth, Asteroid) the end of the dinos Best regards, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Newbie question: multi-methods in Haskell
Dan Weston wrote: Remember that type classes do not provide object-oriented functionality. The dispatch is static, not dynamic. Although OOP can be simulated in Haskell, it is not a natural idiom. If you need dynamic dispatch (including multiple dispatch), you may want to reconsider your solution. Dynamic dispatch is easily added to Haskell code by using an existential to represent any collision: {-# OPTIONS_GHC -fglasgow-exts -fallow-undecidable-instances -fallow-overlapping-instances #-} module Collide where -- Changed to a single param to make life easier... class Collide a where collide :: a - String data Solid = Solid data Asteroid = Asteroid data Planet = Planet data Jupiter = Jupiter data Earth = Earth instance Collide (Asteroid, Planet) where collide (Asteroid, Planet) = an asteroid hit a planet instance Collide (Asteroid, Earth) where collide (Asteroid, Earth) = the end of the dinos -- Needs overlapping and undecidable instances instance Collide (a, b) = Collide (b, a) where collide (a,b) = collide (b, a) -- This is how you get dynamic dispatch in Haskell data Collision = forall a. Collide a = Collision a instance Collide Collision where collide (Collision a) = collide a -- ghci output *Collide let ae = Collision (Asteroid, Earth) *Collide let pa = Collision (Planet, Asteroid) *Collide collide ae the end of the dinos *Collide collide pa an asteroid hit a planet *Collide map collide [ae, pa] [the end of the dinos,an asteroid hit a planet] Best regards, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Newbie question: multi-methods in Haskell
peterv wrote: This is very nice, but it does not really solve the original problem. To get Haskell to choose the best fit it's necessary to encode the location of each element in the hierarchy, so that elements deeper in the hierarchy are more instantiated than those at the top. Then instance selection chooses the best fit by just choosing the most instantiated match. Encoding can be done using phantom types, so a generic solid has the path IsSolid s a planet has IsSolid (IsPlanet p) and a specific planet eg Earth has path IsSolid (IsPlanet Earth) A newtype can be used to associate the path with the actual object: newtype InH path body = InH body so Earth is represented by InH Earth :: InH (IsSolid (IsPlanet Earth)) Earth A class with a functional dependency gives us the mapping between concrete objects and the objects as viewed by the hierarchy: class ToH body path | body - path where toH :: body - InH path body toH = InH The functional dependency means that the path (location in the hierarchy) is uniquely determined by the body, and instance decls then define this relationship: instance ToH Asteroid (IsSolid Asteroid) instance ToH Jupiter (IsSolid (IsPlanet Jupiter)) instance ToH Earth (IsSolid (IsPlanet Earth)) The code is below but as you can see the OOP encoding in Haskell becomes quite heavy and clunky so this style is probably not ideal for a real program - Tillmann's suggestion to use algebraic datatypes instead is more idiomatic - but anyway here goes: {-# OPTIONS_GHC -fglasgow-exts -fallow-undecidable-instances -fallow-overlapping-instances #-} module Collide where class Collide a where collide :: a - String data Asteroid = Asteroid data Jupiter = Jupiter data Earth = Earth data IsSolid a data IsPlanet a newtype InH path body = InH body class ToH body path | body - path where toH :: body - InH path body toH = InH instance ToH Asteroid (IsSolid Asteroid) instance ToH Jupiter (IsSolid (IsPlanet Jupiter)) instance ToH Earth (IsSolid (IsPlanet Earth)) data Collision = forall a. Collide a = Collision a mkCollision :: (ToH a pa, ToH b pb, Collide (InH pa a, InH pb b)) = a - b - Collision mkCollision a b = Collision (toH a, toH b) instance Collide (InH (IsSolid a) aa, InH (IsSolid b) bb) where collide _ = generic collision instance Collide (InH (IsSolid Asteroid) Asteroid, InH (IsSolid (IsPlanet bb)) cc) where collide _ = an asteroid hit a planet instance Collide (InH (IsSolid (IsPlanet a)) aa, InH (IsSolid Asteroid) Asteroid) where collide _ = an asteroid hit a planet instance Collide (InH (IsSolid Asteroid) Asteroid, InH (IsSolid (IsPlanet Earth)) Earth) where collide _ = the end of the dinos instance Collide (InH (IsSolid (IsPlanet Earth)) Earth, InH (IsSolid Asteroid) Asteroid) where collide _ = the end of the dinos instance Collide Collision where collide (Collision a) = collide a --- ghci output *Collide mapM_ putStrLn (map collide [ mkCollision Asteroid Earth , mkCollision Earth Asteroid , mkCollision Jupiter Asteroid , mkCollision Asteroid Jupiter , mkCollision Asteroid Asteroid ]) the end of the dinos the end of the dinos an asteroid hit a planet an asteroid hit a planet generic collision *Collide Best regards, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: monad subexpressions
On Fri Aug 3 06:06:31 EDT Neil Mitchell wrote: What are the semantics of do b f (- a) where does the evaluation of a get lifted to? I suggest the execution of (a) should be done immediately before the action obtained by applying the monadic function whose argument it is part of: do b ( a = \ra - f ra) Similarly, I'd desugar if (- a) then f (- b) else g (- c) to a = \ra - if ra then (b = \rb - f rb) else (c = \rc - g rc) I think it would just be confusing to have to think about lines in the do block since do blocks are just syntactic sugar. The only possible thing that might be needed by the do block is to define what monad the action should be evaluated in. Perhaps the rule could be that if (- a) occurs in some expression the compiler should search for the nearest enclosing do block to identify which monad (a) should be evaluated in, then should again search outwards from the expression (- a) to find the nearest enclosing expression (mexp) which yields a result in that same monad, then desugar to (a = \ra - mexp') where mexp' is obtained from mexp by replacing that occurrence of (- a) by (ra). (Evaluations would be done in the same order as depth first traversal of their occurrences in mexp) Regarding objections by others about (- a) being confused with a section, (-) is not a valid operator therefore it can't be part of a section so no confusion should arise imho... Best regards, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Using Haskell to investigate ML's value restriction
Hi, Ii is interesting that in ML, the presence of mutable ref cells and parametric polymorphism requires the whole language to be dominated by a value restriction [1] to ensure that the type system remains sound, whereas in Haskell, because IORef's can only be created (and used) in the IO monad, no such restriction is necessary. I've often wondered why such a simple thing as using a monad has this magical effect, especially since it seems to me that the real problem lies in the fact that type variables in HMD type inference are not generalised properly due to the absence of an explicit representation of the quantifier, so I decided to try using Haskell's more modern type system to investigate further, using the IO monad together with (unsafePerformIO) and (evaluate) to simulate the execution of an ML program: {-# OPTIONS_GHC -fglasgow-exts #-} module Test where import Data.IORef import System.IO.Unsafe (unsafePerformIO) import Control.Exception (evaluate) ref v = unsafePerformIO $ newIORef v put r f = unsafePerformIO $ writeIORef r f get r = unsafePerformIO $ readIORef r -- Gives a core dump as expected test1 :: IO () test1 = do let r = ref (\x - x) evaluate (put r (\x - x + 1)) evaluate (get r True) return () (test1) is based on one of the ML examples in [1], and when executed, causes a segmentation fault. The reason seems to be the strange type that is assigned to (r): *Test let r = ref (\x - x) *Test :t r r :: forall t. IORef (t - t) *Test (To run this you need to use ghci -fglasgow-exts Test.hs to get ghci 6.6.1 to display the quantifier.) What's strange (to me) about the above typing is that the forall has moved outside the IORef constructor. In other words, although we supplied the constructor with a function which can operate on any value, we got back something which, for any value, contains a function which can operate on it. The reason afaics that (test1) goes wrong is that the let binding causes (r) to be bound to the type above, so the argument matches both forall a. Num a = a - a and Bool - Bool so the action (evaluate (get r True)) tries to apply a function which expects a number to a Bool. However if we add an explicit type to (r) to get (what I see as) the expected quantification, the type checker correctly rejects the program: test2 :: IO () test2 = do let r :: IORef (forall a. a - a) = ref (\x - x) evaluate (put r (\x - x + 1)) evaluate (get r True) return () no instance for Num a ... which might seem like a reason not quite related to our chain of thought so I also tested this using: test3 :: IO () test3 = do let r :: IORef (forall a. a - a) = ref (\x - x) evaluate (put r (\'c' - 'c')) evaluate (get r True) return () which gives couldn't match expected type `a' (a rigid variable) against inferred type `Char'. In other words, the IORef must always contain a function that works with anything - we can't just give it a more specialized function, so the program is rejected for the reasons we expect. Interestingly, even without type annotations, if we use a case instead of a let, the typechecker also rejects the program: test4 :: IO () test4 = case ref (\x - x) of r - do evaluate (put r (\'c' - 'c')) evaluate (get r True) return () this time by noting that (Bool - t) does not match (Char - Char). This illustrates (afaiu) that case does not introduce any quantification, in contrast to let hence the uninstantiated meta-tyvars of r have to unify with both its uses. In conclusion, it seems that the magic given by always having to use IORef's inside the IO monad (without unsafePerformIO of course) is due to the fact that when used this way types involving IORefs never get generalized wrongly since they're never created by a let binding. Another conclusion is that if we wanted at some point to have another new strict language with Haskell's nice type system and syntax as an alternative to the ML family, and we also wanted to have references (and continuations), then either the rule for generalizing the meta-type variables in a let binding would have to be changed or else we would still have to use monads. I'd be interested to know if the use of impredicative types would automatically solve the wierd quantification problem, since: *Test :t ref ref :: forall a. a - IORef a therefore applying this to an argument of type (forall b. b - b) should hopefully give a result of type (IORef (forall b. b - b)), thus the use of impredicative types might allow such a strict variant of Haskell to use side-effects instead of monads while still retaining type soundness... ? Best regards, Brian. [1] http://www.smlnj.org/doc/Conversion/types.html ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: haskell's prefix exprs
Christian Maeder wrote: Hi, I would like haskell to accept the following (currently illegal) expressions as syntactically valid prefix applications: f = id \ _ - [] g = id let x = [] in x h = id case [] of [] - [] i = id do [] j = id if True then [] else [] The rational is that expressions starting with a keyword should extend as far as possible (to the right and over several lines within their layout). On page 15/16 of the H98 report I think this could be achieved by: exp10 ::= fexp fexp ::= [fexp] keyexp keyexp ::= \ apat ... - exp | let ... | ... | aexp (In fact, maybe for haskell' $ could be changed to a keyword.) Alternatively the # symbol could be removed from the pool of symbol chars and used to construct syntactic sugar so you could use f = id #$ \_ - [] to mean exactly f = id (\_ - []) I think when the idea of $ arose originally people didn't at that time know about the many cases where the use of $ is not semantically equivalent to explict brackets, since this knowledge probably only arose later with the introduction of rank-n polymorphism. (Of course the need for #$ would be fixed with impredicative types as in MLF.) Best regards, Brian. ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: 64-bit windows version? (Haskell is a scripting language too!)
skaller wrote: The key thing for the building portability is that the C and C++ compilers are represented by Python classes. There is a pre-programmed class for gcc, and another for MSVC++. I suggest (for GHC) a Haskell class with instances for the different combinations of compilers and platforms and optimization levels. (a) Pick a portable scripting language which is readily available on all platforms. I chose Python. Perl would also do. If I had time to look into improving the GHC build system I'd definitely use Haskell as the scripting language. What's the point of having to learn more than one language to accomplish a task? Surely it is more productive to add functionality to a single language (especially when it's only a case of writing some libraries) rather than grappling with the different syntaxes and limitations and quirks of a multitude of languages/tools and the problems of trying to get them all to work harmoniously together on different platforms? In concrete terms, for each sub-project within GHC ie each directory of source files I'd have a little Haskell program that was responsible for building that sub-project. Kind of like CM.make or the ML Basis system, except with the full power of Haskell so that complicated things such as building successive boot levels could easily be automated. (Ie instead of having a special tool like make that is invoked on dead data (supplied by autoconf etc) to drive the build process, instead use Haskell as a scripting language.) The top level build would be done by another Haskell program which delegated responsibility to the sub-programs in each directory. I'd include the complete source code for all the Haskell tools like Alex and Happy so they could be built the same way. In other words, the entire GHC project would be built by running a single Haskell program, and every single piece of source would either be a Haskell module or a file that is the input to a Haskell program that the main build-driver has built first (from Haskell sources). Therefore there would be no dependency on anything except GHC itself. To port GHC to a completely new platform, you'd of course need a Haskell compiler or interpreter already. However to bootstrap the process only a slow interpreter would be needed so as long as a portable pre-built bytecode version was available for download the only thing left to port would be a byte code interpreter which could just be a single file of c code. Perhaps this is too long-term a vision for solving the short term problems, but maybe it could be the basis of some future projects? Best regards, Brian. ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Why do we have stack overflows?
Brandon Michael Moore wrote: On Thu, May 03, 2007 at 04:59:58PM -0700, John Meacham wrote: I believe it is because a stack cannot be garbage collected, and must be traversed as roots for every garbage collection. I don't think there are any issues with a huge stack per se, but it does not play nice with garbage collection so may hurt your performance and memory usage in unforeseen ways. Isn't it just the top of the stack that has to be treadted as a root? No, because the functions below the top are still active and would usually be referencing other heap locations not visible to the top function. On another note, why use stacks in the first place? Couldn't all activation records just be heap allocated? Regards, Brian. ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: GHC 6.6.1 Windows installer, test version
Neil Mitchell wrote: Hi, I've prepared a GHC 6.6.1 Windows installer. Before I offer this up as an official installer, could people please test it? http://www.haskell.org/ghc/dist/6.6.1/ghc-6.6.1-i386-windows-test1.exe Thanks Neil, This works perfectly! Best regards, Brian. ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Trouble trying to find packages for ubuntu linux
Thanks to everyone for sending me info on how to install ghc6.6 on Ubuntu. The way I used eventually was one sent to me off list and uses the generic i86 linux at http://www.haskell.org/ghc/download_ghc_66.html#x86linux The exact steps I used after downloading the tarball at the above URL to my Desktop were: ~$ mkdir ghc-6.6 ~$ mkdir tarball ~$ mv Desktop/ghc-6.6-i386-unknown-linux.tar.bz2 tarball ~$ cd tarball ~/tarball$ tar -jxvf ghc-6.6-i386-unknown-linux.tar.bz2 ~/tarball$ sudo apt-get install libreadline4 libncurses5 ~/tarball$ cd ghc-6.6 ~/tarball/ghc-6.6$ ./configure --prefix=$HOME/ghc-6.6 ~/tarball/ghc-6.6$ make install ~/tarball/ghc-6.6$ cd ../.. ~$ gedit .bashrc and added $HOME/ghc-6.6/bin to my PATH (must be no spaces in the line below): export PATH=$HOME/ghc-6.6/bin:$PATH Then closed the terminal and opened a new terminal and lo! ghc, ghci, and many libraries are now available! :-) Thanks again for the other suggestions also - I chose the above method just because it will allow me to easily try out different versions of ghc in future while still being able to keep the 6.6 version around just by changing my PATH to whatever version I want to use. Best regards, Brian. ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Problem exporting Haskell to C via a DLL in GHC 6.6
Simon Peyton-Jones wrote: I don't think there is any reason in principle why GHC can't generate DLLs that just work, but plainly it's deficient at the moment. The fundamental reason is that the DLL mechanism itself doesn't allow initialization/ shutdown do be hidden from the user of a DLL, because the order of loading/unloading DLLs is unspecified by the MS Windows operating system. Therefore it's not a GHC problem - it's just a fact of life with DLLs... The other thing is that we could do with more how to documentation about GHC and DLLs. We have a bit here: http://haskell.org/haskellwiki/GHC/Using_the_FFI Could you expand it in the light of your experience? I've added a section http://haskell.org/haskellwiki/GHC/Using_the_FFI#Beware_of_DllMain.28.29.21 which attempts to explain why init/exit code can't be put in DllMain, as well as an *untested* example to show what I meant by putting init/exit code in Begin/End functions instead. I've put a note next to the example to say that it's untested, and to appeal to anyone with more knowledge of static linking between Haskell and C to fix anything I've missed or replace with a better example. (Apologies for not testing it but static linking to stubs generated by GHC seems to require the DLL to be compiled by gcc and use of gcc on Windows seems to require Cygwin since gcc doesn't seem to understand Windows paths and I don't have Cygwin installed - unfortunately at the moment I don't have time to pursue this further.) Best regards, Brian. -- http://www.metamilk.com ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Problem exporting Haskell to C via a DLL in GHC 6.6
SevenThunders wrote: Brian Hulley wrote: SevenThunders wrote: DllMain if (reason == DLL_PROCESS_DETACH) { shutdownHaskell(); return TRUE; } The above *may* be the problem: it is unsafe to do anything in DllMain that... Instead of trying to start/shutdown Haskell from DllMain, I'd export a Begin() and End() function from the DLL and explicitly call these from your application's main(). So in your scheme the Begin() would call the startupHaskell function and the End() call the shutdown Haskell? Yes. Or would the Begin initiate the linking to the specific DLL using LoadLibrary? Since Begin would be a function exported by the DLL, Windows would ensure that the DLL was loaded when it is first called from your application if it was not already loaded so there would be no need for an explicit call to LoadLibrary. and then End specifically unload the library; or both? I wouldn't bother explicitly unloading the library - I'd leave this up to Windows. The importance of using an End function is that you can ensure that the call to shutdown Haskell happens at a time when all DLLs needed by Haskell are still available, whereas using DllMain to do the shutdown call is dangerous because DllMain may be invoked when some DLL necessary for Haskell to shutdown has already been unloaded by Windows. Ideally there would also be some way to call Begin/End when using the DLL from Matlab but I don't know anything about Matlab so can't help with this. A quick hack to enable you to use the DLL safely from your application (using Begin/End) as well as unsafely from Matlab (relying on DllMain to shutdown Haskell), would just be to have a flag in the DLL to keep track of whether you've already shut Haskell down. Then in the case for process_detach you could just check this so that shutdown would only be called from DllMain as a last resort. Another question I have is, is it possible to create a statically linked Haskell library that can be linked using MS VC tools? Also I must say I am a bit confused about the use of the routine __stginit_Bad. Suppose I had multiple Haskell modules each with their own functions to export. Which __stginit_??? routine do I use? I don't know - hopefully someone else may be able to answer this question. Best regards, Brian. -- http://www.metamilk.com ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: List syntax (was: Re: help from the community?)
Douglas Philips wrote: On 2007 Feb 3, at 2:55 AM, Brian Hulley indited: I know, I find the need to manually delete and insert commas extremely tedious as well. This is why I proposed: ... I like that. (I haven't done enough analysis on the layout part of the grammar to personally make sure it is ok.) The #( sugar ... Bulat Ziganshin wrote: Saturday, February 3, 2007, 10:55:52 AM, you wrote: bracket_ (enter a) (exit a) (do b c)-- looks like LISP... this pattern is very typical in my programs and i use '$' before last parameter I've written more details (and made some improvements to my original idea) at http://www.haskell.org/haskellwiki/Accessible_layout_proposal Brian. -- http://www.metamilk.com ___ Haskell-prime mailing list Haskell-prime@haskell.org http://www.haskell.org/mailman/listinfo/haskell-prime
[Haskell-cafe] Proposal for allowing more use of layout to avoid parentheses and commas
Hi, Following a recent thread on the Haskell' mailing list about the nusiance of having to deal with commas in tuples (when cutting and pasting things to re-order the elements there's always a pesky comma left over in the wrong place), I've written up a proposal for a very simple syntax tweak that would allow you to use the layout rule for function arguments, tuple/list/record contents etc for some future version of Haskell at http://www.haskell.org/haskellwiki/Accessible_layout_proposal This post is not intended to spark a lot of discussion just to point out the existence of the page for anyone interested. I've also added a link to all the new proposals from http://www.haskell.org/haskellwiki/Future . (If I don't reply to any follow up posts to this thread it's not because I'm ignoring them. It will just be because I have to try to get down to actually writing more of my program in the next few weeks, and I find thinking up ideas and reading posts, books, cooking, shopping, watching dvds etc, is infinitely more diverting than the painstakingly hard work of actual coding (though of course it's great in the rare occasions when things fall into place) ... ;-)) Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: List syntax (was: Re: help from the community?)
Douglas Philips wrote: What would be the proper way to propose that: ( exp1 , ... , expk ) (tuple, k=2) [ exp1 , ... , expk ] (list, k=1) be amended to: ( exp1 , ... , expk [ , ] ) (tuple, k=2) [ exp1 , ... , expk [ , ] ] (list, k=1) I think a problem with the above proposal is that by allowing an optional trailing comma the compiler can no longer detect as an error the case where the programmer has simply just forgotten to fill in the last element of the tuple/list. The existing syntax forces the user to do some extra work fiddling about with commas but the reward is that the compiler can verify that you haven't forgotten the last argument. About a year ago I proposed (on the cafe) a syntax sugar to avoid commas in tuples and lists which made use of the layout rule something like: let a = #[-- introduces new layout block first second third let b = #( one two As an aside it would also be nice to be able to use layout for function arguments as in: do a - foo #bracket_ enter exit action the general idea being that '#' immediately followed by an identifier (which may be qualified) or the symbol '(' or '[' would start a layout block. ('#' of course would no longer be able to be used in symbolic identifiers) Brian. -- http://www.metamilk.com ___ Haskell-prime mailing list Haskell-prime@haskell.org http://www.haskell.org/mailman/listinfo/haskell-prime
Re: List syntax (was: Re: help from the community?)
Douglas Philips wrote: On 2007 Feb 2, at 1:03 PM, Neil Mitchell indited: Personally I'd make the rule that trailing commas are never allowed, anywhere, but I do see an argument for adding them to import lists. You just highlighted the inconsistency: You refer to import lists... you appear to think of the import syntax _as a list_, and it is precisely that mental processing where the inconsistency hits/grates. If it is an import _list_ it can have trailing commas, but if it is some other _list_, it can't. I don't see the justification for making those two cases different. I don't either, but I'd agree with Neil that trailing commas shouldn't be allowed anywhere, but would reject the argument of allowing them in import lists since it just seems to me that this was to save someone making the trivial effort to make their code look tidy and complete. Apart from the extra possibility for errors (yes I understood that you'd define it to not be an error but this doesn't change the fact that for people who always wrote their tuples using the normal mathematical convention not using an optional trailing comma it would be an error in their code) to go undetected, it would just substitute one inconsistency for another: as Malcolm pointed out the syntax (,,) represents the constructor for a 3-tuple therefore: let a = (x,y,)-- in your proposal a 2-tuple let b = (,,) x y -- still a 3-tuple with a missing element I think this would just be far too confusing: the choice to use (,) to represent the pair constructor is IMHO too deeply ingrained in existing Haskell code to change it to mean a 1-tuple (also do we want to add the concept of 1-tuples to the language?). Also, I think in maths the convention is to use commas as separators when writing down coordinates etc. From a personal aesthetic point of view the appearance of a trailing comma is highly irritating to me like passing a shelf in a shop where someone has left a book unsettled with the cover twisted over the edge at an annoying angle and some pages crumpled up, that forces me to stop and fix it... :-) Regarding import/export lists, in some ways I think the {;} syntax should have been used instead then the layout rule could have been applied to good effect to get rid of the need for any separators eg: module Foo #-- # introduces a layout block {;} Bar # Con1 Con2 where import Control.Monad.Trans # MonadIO{..} MonadTrans{..} (Though the above is obviously too radical a departure for Haskell') Brian. -- http://www.metamilk.com ___ Haskell-prime mailing list Haskell-prime@haskell.org http://www.haskell.org/mailman/listinfo/haskell-prime
Re: List syntax (was: Re: help from the community?)
Douglas Philips wrote: On 2007 Feb 2, at 11:25 PM, Brian Hulley indited: Apart from the extra possibility for errors (yes I understood that you'd define it to not be an error but this doesn't change the fact that for people who always wrote their tuples using the normal mathematical convention not using an optional trailing comma it would be an error in their code) Well it would now, but in my proposal it wouldn't be. So it would not make any correct code incorrect. Of course, but when I said error I meant error with respect to the intentions of the programmer not syntax error detected by the compiler. The problem with your proposal is that if optional trailing commas were allowed, if *I* wrote: (1,2,) by mistake, forgetting to add in the last element, the fact that the compiler would now treat the trailing comma as optional means it would now accept the code as being syntactically ok. If *you* wrote that same code, it *would* correspond to what you meant ie just (1,2), for me it would not because I'd have meant to write something like (1,2,3), so for me, instead of a nice simple syntax error I'd get a confusing type error possibly somewhere else in the code therefore my net productivity would be reduced. However a compiler option could be used to switch the optional trailing comma feature on and off and therefore suit everyone. to go undetected, it would just substitute one inconsistency for another: as Malcolm pointed out the syntax (,,) represents the constructor for a 3-tuple therefore: let a = (x,y,)-- in your proposal a 2-tuple let b = (,,) x y -- still a 3-tuple with a missing element Prelude :t (1,2,) 3 ERROR - Syntax error in expression (unexpected `)') Prelude :t (1,2,) ERROR - Syntax error in expression (unexpected `)') Prelude Again, this would not break existing code, since there is no mechanism for section'd tuples. What I meant was that the number of commas for a constructor is fixed: always 2 commas means a constructor for a 3-tuple. However you'd now have a choice of how many commas to use when writing out the sugared saturated application - either 2 or 3 commas. Which seems inconsistent, since in 5 years time someone used to always writing a pair like: let pair = (1,2,)-- trailing commas now very popular might quite sensibly want to write this as let pair = (,,) 1 2 (since the whole point of the (,,) syntax is that the number of commas is the same as that used when writing out the value in tuple notation) but we can't have a programmer choice when it comes to the constructor: the compiler writer must choose one way or the other. So I don't think there should be a choice in the sugar syntax either. Then if we choose to use (,,) to represent the pair constructor because of the popularity of trailing commas in the applied syntax, this would beg the question of what (,) would represent hence the spectre of introducing 1-tuples... Also, I think in maths the convention is to use commas as separators when writing down coordinates etc. ??? I don't quite get the applicability here... Perhaps it is not applicable, but I thought a guiding principle of Haskell syntax was to try and stay as close to normal mathematical notation where possible, and I remember learning 2d coordinates in school as (x,y) not (x,y,). From a personal aesthetic point of view the appearance of a trailing comma is highly irritating to me like passing a shelf in a shop where someone has left a book unsettled with the cover twisted over the edge at an annoying angle and some pages crumpled up, that forces me to stop and fix it... :-) Well, if we're going to bring personal points of view in, it highly pisses me off that in a construct such as: ( expr , expr , expr , expr , expr , ) I have to be vigilant to remove that trailing comma when it is in _no way_ ambiguous. I know, I find the need to manually delete and insert commas extremely tedious as well. This is why I proposed: #( expr expr as sugar for (expr, expr), because it seems crazy to me that we've got all the machinery in place in the form of the layout rule yet we can only use it for a handful of built in constructs, when everywhere else we still need to juggle with commas and try to make parentheses as invisible as possible eg: bracket_ (enter a) (exit a) (do b c)-- looks like LISP... instead of just: #bracket_ enter a exit a do b c [snip] I don't think we're ever going to get agreement on apparently irreconcilable personal aesthetics, but perhaps we can apply some principles, such as regularity and consistency and both get what we want? The #( sugar would only go part of the way to address your proposal since it doesn't address tuples written inline
Re: help from the community?
Taral wrote: On 1/31/07, Conor McBride [EMAIL PROTECTED] wrote: So, as far as Haskell' is concerned, I'd favour forbidding non-empty cases, but only because I favour having some more explicit syntax for empty cases, further down the line. I see nothing wrong with case x of {}, with required braces. The layout rule never generates empty braces. main = do a - do b - something case b of return a Doesn't the layout rule convert the above to: main = do { a - do { b - something; case b of {}}; return a} ^^ empty braces In any case I thought the layout rule was supposed to be regarded as just a convenience rather than making a distinction between explicit braces and braces added by the rule? Also, can anyone explain why empty case constructs are needed? Why not just write undefined? Brian. -- http://www.metamilk.com ___ Haskell-prime mailing list Haskell-prime@haskell.org http://www.haskell.org/mailman/listinfo/haskell-prime
Re: [Haskell-cafe] Re: Channel9 Interview: Software Composability andtheFu ture of Languages
Donald Bruce Stewart wrote: magnus: All I'm trying to say is that imperative thinking is so common outside of CS/math and we learn it so early on in life that we probably can consider it the natural thinking way. foldl (\water dish - wash water dish) soapywater dishes :: [Dishes] ^^ type error I hope they weren't expensive dishes because as each dish is washed it dissolves into the water never to be seen again! :-) Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: help from the community?
Andres Loeh wrote: The only reasons that I could see in favor of allowing empty foralls is that it might be easier to automatically generate code. Haskell seems to be a bit inconsistent in how it treats empty constructs. For example, empty let and empty where seems to be allowed, but not an empty case? Just a little remark on the side: 'If' and 'case' demand exactly one expression. In such cases allowing zero expressions is not a generalization but an unnecessary complication. 'Let' and 'where' allow any number of bindings, so allowing zero bindings (instead of demanding at least one) is a simplification. I meant the branches of a case (the report specifies at least 1). I think it's important to keep some possibility for the compiler to detect probable errors as syntax errors. If all syntax is inhabited by strange defaults then this just means simple errors will go undetected eg: let a = case foo of Here, the user has probably got sidetracked into editing some other part of the program and just forgotten to get back to fill in the cases for the case construct. Allowing zero cases means the user will get a strange runtime error instead as the function part of the case is undefined. let z = \y (foo y) Here, it seems clear that the user has just forgotten to type the - which means a simple syntax error would get transformed into a much more puzzling (esp for a newbie) type error. The difference between the above and 'let' and 'where' is that if the enclosing construct (eg a binding) is complete, we know that the contents of the 'let' are complete (since extra local bindings added afterwards would be irrelevant) similarly for 'where', and if the enclosing construct is not complete the compiler will detect this. Therefore I think the original choices are the best since they don't seem inconsistent when looked at this way. Brian. -- http://www.metamilk.com ___ Haskell-prime mailing list Haskell-prime@haskell.org http://www.haskell.org/mailman/listinfo/haskell-prime
Re: [Haskell-cafe] Trouble understanding records and existential types
On Thursday, January 25, 2007 7:08 AM, John Ky wrote: On 1/25/07, Brandon S. Allbery KF8NH [EMAIL PROTECTED] wrote: I'm probably missing something, but: (a) Why not: data ANode = Branch { name :: String, description :: String, children :: [AnyNode] } | Leaf { name :: String, value :: String } -- this reuse Would I be able to this? getLeaves :: ANode - [Leaf] If not, is it the case that people generally don't bother and do this instead? getLeaves :: ANode - [ANode] As has been pointed out, Leaf is a data constructor not a type so you'd have to use [ANode]. Inspired by the problem I tried a GADT: data IsLeaf data IsBranch data ANode a where Branch :: String - String - [forall b. ANode b] - ANode IsBranch Leaf :: String - String - ANode IsLeaf getLeaves :: ANode IsBranch - [ANode IsLeaf] getLeaves (Branch _ _ ls) = leaves ls leaves :: [forall b. ANode b] - [ANode IsLeaf] leaves (l@(Leaf _ _) : ls) = l : leaves ls leaves (Branch _ _ ls : lls) = leaves ls ++ leaves lls but unfortunately the above code generates the following error by GHC6.6: Couldn't match expected type `forall b. ANode b' against inferred type `ANode a' In the pattern: Leaf _ _ In the pattern: (l@(Leaf _ _)) : ls In the definition of `leaves': leaves ((l@(Leaf _ _)) : ls) = l : (leaves ls) Just out of curiosity, does anyone know why the above code doesn't compile ie why is the inferred type for the pattern: Leaf _ _ (ANode a) and not (ANode IsLeaf)? Thanks, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Trouble understanding records and existential types
Chris Kuklewicz wrote: This is how I would write getLeaves, based on your GADT: data IsLeaf data IsBranch newtype Node = Node { getNode :: (forall c. ANode c) } data ANode :: * - * where Branch :: String - String - (ANode a,ANode b) - [Node] - ANode IsBranch Leaf :: String - String - ANode IsLeaf getLeaves :: ANode a - [ANode IsLeaf] getLeaves (Branch _ _ (l1,l2) rest) = getLeaves l1 ++ getLeaves l2 ++ concatMap (getLeaves.getNode) rest getLeaves x@(Leaf {}) = [x] Thanks Chris - that's really neat! I see it's the explicit wrapping and unwrapping of the existential that solves the typechecking problem, and the use of newtype ensures there's no run-time penalty for this. Also the wrapping of the existential allowed higher order functions to be used making the code much neater. Regarding the question of why in the original example the typechecker was trying to match (forall b.ANode b) against (ANode a) and not (ANode IsLeaf), I think the answer is probably that the typechecker first finds the MGU of the types occupying the same position in all the left hand sides first, then it tries to match this against the declared type at that position, whereas for the original example to have typechecked it would have to treat each equation separately. Anyway it's now an irrelevant point given the clarity of your solution which compiles fine, Best regards, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] basic field questions
jamin1001 wrote: Hi, I am new at Haskell and have some basic questions. So then how should this be done? What if I want to do something like data Chair = Chair {pos:: Int, color :: Int} data Table = Table {pos:: Int, color :: Int} Unfortunately you have to think up different names for all constructors and field names that are declared anywhere in the same module. A possible methodical way to do this is to prefix all names by the type name (with first letter lowercase of course) eg: data Chair = Chair {chair_pos:: Int, chair_color :: Int} data Table = Table {table_pos:: Int, table_color :: Int} The reason is that when you declare a fieldname this also introduces a top level function with the same name which returns the relevant component of the record ie in the above the following top level functions are generated by the compiler: chair_pos :: Char - Int chair_color :: Chair - Int table_pos :: Table - Int table_color :: Table - Int Also, could someone tell me why this doesn't compile in GHC: data Test = A {a::Int} | B {a::Int, b::Int} data Test2 = C {c::A} (Test2 line): Not in scope: type constructor or class 'A' (A) is a data constructor whereas you need a type here, so it should be: data Test2 = C {c :: Test} Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell] Views in Haskell
Simon Peyton-Jones wrote: http://hackage.haskell.org/trac/haskell-prime/wiki/ViewPatterns I'm thinking of implementing it in GHC, so I'd be interested in feedback of the form - how desirable is it to have a feature of this general form? - can this particular proposal be improved? Regarding the syntax, I don't like the use of -, because I think it is confusing to write even - n when even is the function itself. In all other places in Haskell, A - B represents a function from A to B whereas in the proposal A - B represents the function A applied to the thing currently being matched which may return a value wrapped up in Maybe which matches B. There are 2 things - the inconsistent use of - and the implicit Maybe. I'd rather the Maybe was not implicit (as described in extension 2), and a more consistent syntax was found. A possible syntax could represent the value being matched explicitly, say using ? to represent the value currently being matched, then the pattern could be written as an equation: f (prodSize ? = Small) = ... f (prodSize ? = Medium) = ... f (prodSize ? = Big) = ... or simulating an n + k pattern: g (? - 3 = n) = ... or a function which checks its arg satisfies an arbitrary expression: h (? - (3 * ?) = 10) = ... or an n+k against the second element of a list j ( toList ? = (_ : (? - 3 = n : _))) = ... Regarding the problem itself, I'm still not sure why views are needed. For example in (f) above, why not just write as: f :: Product - ... f prod = k (prodSize prod) where k = ... Best regards, Brian. -- http://www.metamilk.com ___ Haskell-prime mailing list Haskell-prime@haskell.org http://www.haskell.org/mailman/listinfo/haskell-prime
Re: [Haskell-cafe] IO is not a monad
Yitzchak Gale wrote: I wrote: Prelude let f .! g = ((.) $! f) $! g Prelude let f = undefined :: Int - IO Int Prelude f `seq` 42 *** Exception: Prelude.undefined Prelude ((= f) . return) `seq` 42 42 Prelude ((= f) .! return) `seq` 42 42 Duncan Coutts wrote: Perhaps I'm missing something but I don't see what's wrong. The monad laws say that (= f) . return must be identical to f. I thought it was: return x = f = f x so here the lhs is saturated, so will hit _|_ when the action is executed just as the rhs will. I think the problem you're encountering is just that the above law doesn't imply: (= f) . return = f in Haskell because the lhs is of the form \x - _|_ whereas the rhs, which should really be of the form \x - _|_, is actually _|_ already(!) so the _|_ has effectively been allowed to jump to the left of the arrow hence the inequality detected by seq. Perhaps a solution would be to force _|_ to respect the shape of the type, thus non-terminating values of type a - b would be given the value \_ - _|_ instead of _|_ ? Regards, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] IO is not a monad
Brian Hulley wrote: Yitzchak Gale wrote: I wrote: Prelude let f = undefined :: Int - IO Int Prelude f `seq` 42 *** Exception: Prelude.undefined Prelude ((= f) . return) `seq` 42 42 The monad laws say that (= f) . return must be identical to f. I thought it was: return x = f = f x so here the lhs is saturated, so will hit _|_ when the action is executed just as the rhs will. I think the problem you're encountering is just that the above law doesn't imply: (= f) . return = f in Haskell ok so far... because the lhs is of the form \x - _|_ No I got this wrong. Evaluating the lhs to WHNF doesn't hit the _|_. (Incidentally the version using .! evaluates to exactly the same thing since (= f) `seq` ((= f) . return) = ((= f) . return) since (\x - x = f) is already in WHNF afaiu) Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] IO is not a monad
Brian Hulley wrote: Brian Hulley wrote: Yitzchak Gale wrote: I wrote: Prelude let f = undefined :: Int - IO Int Prelude f `seq` 42 *** Exception: Prelude.undefined Prelude ((= f) . return) `seq` 42 42 The monad laws say that (= f) . return must be identical to f. I thought it was: return x = f = f x so here the lhs is saturated, so will hit _|_ when the action is executed just as the rhs will. Ooops! But that does not mean the equation holds because for example Prelude (return 3 = f) `seq` 42 42 Prelude (f 3) `seq` 42 *** Exception: Prelude.undefined In the lhs you only hit _|_ when the composite (=) action is actually being executed whereas in the rhs you hit _|_ when computing the function which will return the action to execute so there is difference. Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Article review: Category Theory
Lennart Augustsson wrote: On Jan 19, 2007, at 08:05 , [EMAIL PROTECTED] wrote: Thus, Hask is not a category, at least not as defined in the article. The problem is that (either) morphisms or the morphism composition ('.') are not internalized correctly in Haskell. And this is why some of us think that adding polymorphic seq to Haskell was a mistake. :( I've often wondered why seq is the primitive and not $! Would this solve the problem? Is there any solution that would allow excess laziness to be removed from a Haskell program such that Hask would be a category? Thanks, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] seq (was: Article review: Category Theory)
Neil Mitchell wrote: Hi Brian, Is there any solution that would allow excess laziness to be removed from a Haskell program such that Hask would be a category? class Seq a where seq :: a - b - b Then you have a different seq based on the types, and it doesn't go wrong. You would probably want deriving Seq support. This seems an amazingly neat solution to a really terrible problem, so: 1) Does anyone know why this was not used in the first place? 2) Would it be good to use this in future versions of Haskell? 3) Is there any practical program which requires the current seq that could not be rewritten to use the typeclass seq? Thanks, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Article review: Category Theory
Johan Gršnqvist wrote: Ulf Norell skrev: On Jan 16, 2007, at 7:22 PM, David House wrote: In the section on the category laws you say that the identity morphism should satisfy f . idA = idB . f This is not strong enough. You need f . idA = f = idB . f (I do not know category theory, but try to learn from the tutorial/article/introduction.) Given this, and looking at the figure accompanying exercise 2. Can I not then show that f=h from: f.g = idA (f.g is A - A and idA is the only morphism A - A, closedness gives the equality) h.g = idA (same argument) g.f = g.h = idB (same argument) thus (using the laws for id and associativity) f = idA . f = (h . g) . f = h . (g . f) = h . idB = h Thus in the figure f=h must hold, nad one arrow can be removed from the graph. But f /= h so by the above reasoning you get a proof by contradiction that the figure is not a category. Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Article review: Category Theory
David House wrote: http://en.wikibooks.org/wiki/Haskell/Category_theory I'd love comments from newcomers and experts alike regarding my approach, the content, improvements and so on. Of course, it's on the wikibook, so if you have anything to add (that's not _too_ substantial otherwise I'd recommend discussion first) then go ahead. Hi David, In the introduction you say that Set is the category of all sets with morphisms as standard functions and composition as standard function composition. But in the second exercise in the intro it's clear that function composition is not associative. Therefore surely this means everything based on function composition can't be a category? Also, why does this exercise contain redundant morphisms (I hope I'm not spoiling it for anyone by saying this or perhaps I've just totally misunderstood everything)? Thanks, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Article review: Category Theory
Brian Hulley wrote: David House wrote: http://en.wikibooks.org/wiki/Haskell/Category_theory But in the second exercise in the intro it's clear that function composition is not associative. Apologies. I got totally confused with the way function composition is back to front etc. I still have no idea what the solution to the second exercise is though. Thanks, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Article review: Category Theory
Yitzchak Gale wrote: David House wrote: I've added a bit more explanation, so it may now be palatable. It is quite a hard exercise, though, perhaps it shouldn't come so early on. In my opinion, it is now much more clear. And it is a very instructive example. If people still find it too hard, you could add the additional hint: Keep in mind that there are no morphisms other than the ones shown in the diagram. Ok I understand it now, because David has just clarified offlist the thing that puzzled me about the diagram: namely that morphisms have an individuality of their own that isn't fully determined by the lhs and rhs of the arrow like the relationship between a function and its type. Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Redefining superclass default methods in a subclass
Meng Wang wrote: Hi Brian, Thank you for starting the thread. We (Martin Sulzmann and me) proposed a type class extension which allows modular extension of superclasses (a complement of subclass extension). The idea has been shown to be particularly useful in (but not limited to) encodings of generic programming with type classes. A brief introduction of the proposal is documented in our wiki: http://taichi.ddns.comp.nus.edu.sg/taichiwiki/GPHomePage. I will try to add it as a link in yours soon. A more detailed and formal description of the proposal can be found in our Workshop on Generic Programming 06 paper which is available at http://www.comp.nus.edu.sg/~sulzmann http://web.comlab.ox.ac.uk/oucl/work/meng.wang/ Thanks - I've added the above links to http://www.haskell.org/haskellwiki/Class_system_extension_proposal along with a one-line summary which I'm sure is totally imperfect but hopefully not too misleading ;-) Best regards, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Redefining superclass default methods in a subclass
Simon Peyton-Jones wrote: One of the great things about John's class-alias proposal is that John worked out a lot of details and captured them in a web page, rather than it getting buried in an email thread. If you have ideas to refine his proposal, it'd be good to see if, with him, you can come up with a unified design, and again capture it in a Wiki page or something. I've started a page at http://www.haskell.org/haskellwiki/Class_system_extension_proposal John - I haven't added anything about your class alias proposal because you've copyrighted your proposal and I don't want to do the wrong thing ;-) Can you add a section for your proposal (or containing a link to your proposal) on his page? Please could everyone who has any other ideas about class system extensions add them to the page above so that we have a central location. Hopefully it will gradually become clear what all the issues are and perhaps a path for trying to implement some extensions in order of difficulty. Thanks, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Redefining superclass default methods in a subclass
Brian Hulley wrote: Simon Peyton-Jones wrote: One of the great things about John's class-alias proposal is that John worked out a lot of details and captured them in a web page, rather than it getting buried in an email thread. If you have ideas to refine his proposal, it'd be good to see if, with him, you can come up with a unified design, and again capture it in a Wiki page or something. I've started a page at http://www.haskell.org/haskellwiki/Class_system_extension_proposal John - I haven't added anything about your class alias proposal because you've copyrighted your proposal and I don't want to do the wrong thing ;-) Can you add a section for your proposal (or containing a link to your proposal) on his page? ^^^ Apologies for typo - should be this page Best regards, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] why can't you surround (+) in backticks and have it beinfix?
[EMAIL PROTECTED] wrote: David House wrote: You can fake this: (-!) = ($) (!-) = flip ($) foo -! liftM2 (,) !- bar Was anyone in that brainstorm thinking of Chung-chieh Shan's -: and :- (http://www.haskell.org/pipermail/haskell-cafe/2002-July/003215.html) or was the similarity just a really cool coincidence? I hope no-one seriously thinks the above syntax is clearer than: liftM2 (,) foo bar Brian. -- Operators: one small step for compilers, one giant leap for obfuscation. http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Why does the wiki search facility not work properly?
Hi, There is a page on the Haskell Wiki titled Talk:SantaClausProblem subtitled Beautiful concurrency. However typing any of the following into the search box *doesn't* lead to the page: Santa talk:santaclausproblem beautiful beautiful concurrency Talk:Santa In fact to get the page you have to type the *exact* full title in the *exact* case. Luckily I could always refer back to SimonPJ's post to the Haskell mailing list to find the link to the page, but I think this situation is really bad because it means that things on the wiki are more or less just being thrown down a gaping void never to be seen again unless you know which catagories to look in from the main page. Another point is that the word beautiful does occur on the page but the page is not included in the list of page text matches. Perhaps the site is not being automatically re-indexed frequently enough? There is also a bunch of check boxes at the bottom of the search results page that doesn't seem to do anything either except cause nothing at all to happen when you click search unless the (Main) box is the only box ticked. Anyway I thought I'd just point this out in case anyone knows how to fix it. Thanks, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Redefining superclass default methods in a subclass
Bulat Ziganshin wrote: Hello Brian, Thursday, January 4, 2007, 10:00:05 PM, you wrote: deeper, the programmer is burdened more and more by the need to cut-and-paste method definitions between instances because Haskell doesn't allow a superclass (or ancestor class) method default to be redefined in a subclass. i've runned into this problem with Streams library. finally i've decided to wrote bodies of such methods outside of class: [example snipped] Hello Bulat, Thanks for the workaround, which solves the need to copy and paste method bodies though not the problem of having to write out instance decls for a potentially large chain of classes leading to the subclass of interest. Part of the motivation for proposing that a superclass method default could be redefined in a subclass (or a particular instance) is that it would allow some refactorings of the class hierarchy without affecting code that just uses the subclass - in particular it would allow existing code using Monad to compile unchanged even when Monad moved down to Functor = Applicative = Monad because return and = are enough to get completely defined instances for Functor and Applicative. Best regards, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Stupid newbie question
Brian Hurt wrote: nth 0 (x:xs) = Some x nth i (x:xs) = if i 0 then Empty else nth (i-1) xs nth i [] = Empty [blows stack on large i] As other people have pointed out, this is due to laziness. I'd write it like: nth 0 (x:_) = Some x nth i (_:xs) = of i 0 then Empty else (nth $! i-1) xs nth _ [] = Empty where a general rule of thumb is always to replace (fun intexp) by (fun $! intexp) whenever intexp is just a trivial arithmetic expression that doesn't involve traversing (ie forcing of) any other data structure. Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Stupid newbie question
Brian Hulley wrote: Brian Hurt wrote: nth 0 (x:xs) = Some x nth i (x:xs) = if i 0 then Empty else nth (i-1) xs nth i [] = Empty [blows stack on large i] As other people have pointed out, this is due to laziness. I'd write it like: nth 0 (x:_) = Some x nth i (_:xs) = of i 0 then Empty else (nth $! i-1) xs ^^^ -- oops! nth _ [] = Empty I think the above code would be more efficient written as: nth n xs = if n 0 then Empty else nth' n xs where nth' 0 (x:_) = Some x nth' i (_:xs) = (nth' $! i - 1) xs nth' _ _ = Empty since the first 2 cases deal with every situation where we've got a non-empty list and an index = 0 (so no need to keep checking that the index is = 0 in the second case - instead the test can be moved outside the loop) and there's no need to pattern match against [] in the last case because we already know this must be an empty list. (Though in general it's probably a good idea to make each pattern as independent as possible when writing a function so that if some cases of a function are later edited there's more chance of the compiler being able to lead you to errors via the incomplete patterns warning - hopefully the compiler can optimize out any redundant checks) Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Stupid newbie question
Brian Hulley wrote: Brian Hulley wrote: Brian Hurt wrote: nth 0 (x:xs) = Some x nth i (x:xs) = if i 0 then Empty else nth (i-1) xs nth i [] = Empty [blows stack on large i] As other people have pointed out, this is due to laziness. I'd write it like: nth 0 (x:_) = Some x nth i (_:xs) = of i 0 then Empty else (nth $! i-1) xs ^^^ -- oops! nth _ [] = Empty Actually I see I should have read Jeremy Shaw's answer more carefully before giving my own since I'd missed the point about the problem being with the list itself not the decrementing of (i) (which wouldn't be a problem since it is immediately forced on the next iteration by the comparison of i to 0). The answer therefore lies in the laziness of the makelist function which could be solved by: makelist i = i : (makelist $! i - 1) Jeremy Shaw wrote: pps. I didn't explain why [1..100] works, but [1..] fails, because I don't know :) It's a bit suprising to me... I think this might be because the code that produces the list [1..100] would have to be something like: produce n i = if i n then i : produce n (i +1) else [] so each element of the list is now forced by the comparison with n, so even though the end of the list will be a thunk when 100 has not yet been reached, none of the elements are thunks. Anyway it was certainly not a stupid question - thanks for asking it. Best regards, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Redefining superclass default methods in a subclass
Hi, Looking at some of the ideas in http://www.haskell.org/haskellwiki/The_Other_Prelude , it struck me that the class system at the moment suffers from the problem that as hierarchies get deeper, the programmer is burdened more and more by the need to cut-and-paste method definitions between instances because Haskell doesn't allow a superclass (or ancestor class) method default to be redefined in a subclass. For example, consider this part of a proposal for Functor = Applicative = Monad: -- I've just used 'm' so it's easy to see what parts are relevant to Monad class Functor m where fmap :: (a - b) - m a - m b class Functor m = Applicative m where return :: a - m a (*) :: m (a - b) - m a - m b () :: m a - m b - m b ma mb = -- left as exercise for a rainy day! class Applicative m = Monad m where (=) :: m a - (a - m b) - m b The problem with this is that whereas someone defining a Monad at the moment only needs to define (return) and (=), with the above, though it gives obvious advantages in flexibility, generality etc, defining a new Monad involves providing methods (in instance decls) for fmap and (*) as well, and the default method for () is ma mb = (fmap (const id) ma) * mb (from that page above) which I'm sure everyone will agree is a *lot* more complicated than: ma mb = ma = (\_ - mb) Not only is the first definition for () more complicated, it obscures the simple fact that for monads it's just a trivial special-use case of = where the bound argument is ignored. Therefore I'm wondering if it would be possible to allow default methods for a superclass to be defined, or redefined, in a subclass, so we could write: class Applicative m = Monad m where (=) :: m a - (a - m b) - m b mf * ma = mf = \f - ma = \a - return (f a) ma mb = ma = \_ = - mb fmap f ma = ma = \a - return (f a) (I know the above can be written in a more point-free style but I wrote it like that to make it easy to understand what's happening.) The essential point here (excuse the pun :-) ) is that it is impossible to write the default methods in the class in which the operation is defined, because the implementation depends on methods of the relevant subclass (and will therefore be different for different subclasses though not for each particular instance of a given ancestor class of a particular subclass). As Haskell stands at the moment, we are forced to cut and paste identical methods for each individual instance of each ancestor class of a particular subclass because we can't override an ancestor class method in the *class* decl for a subclass. The type class system at present is based on the idea that you can define related methods together and in terms of each other, at one level of the hierarchy. However as the above example shows, related methods sometimes need to be spread over the hierarchy but we still want to be able to define default implementations of them in terms of each other. Perhaps there is some reason this can't be done? Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Redefining superclass default methods in a subclass
Roberto Zunino wrote: Brian Hulley wrote: because Haskell doesn't allow a superclass (or ancestor class) method default to be redefined in a subclass. How one would write instances? Using your Monad class, does instance Monad F where return = ... (=) = ... automatically define an instance for Applicative? Yes, but I'd make the method names be call-site-bound so the actual method that is called is determined by the set of instance decls and class decls visible at each particular call site, and any instances that are automatically created would be hidden by any explicitly defined instances that are visible. If it does: What if there already is such an instance? Which one gets used for ()? The user-defined one or the Monad default? A possible proposal could be: 1) Class and instance decls would allow method implementations to be given for any methods in the class or any ancestor class. 2) Whenever an instance decl is visible there would always be a full set of instance decls for all ancestor classes, by supplementing the set of explicitly given instance decls that are visible by automatically generated implicit instance decls. 3) The most specific method implementation would always be chosen (ie prefer an explicit instance method over a class method and prefer a subclass method to a superclass method) In particular rule 2) would mean that the actual method used depends on what's available at the call site which means that a Haskell program could no longer be thought of as being re-written into a single module before compilation, since the meaning of overloaded names would be determined by (CalledFromModule, Type) not just Type. (The desire to hide instance decls or have different instance decls for the same type within the same program has come up before on the list but unfortunately I can't remember who posted something along these lines or when.) Is separate compilation still possible? (If there is no instance right now, one might pop out in another module...) I think it should still be possible because within a module, the overloadings would be determined by the set of explicitly defined instances in scope in that module. Various optimizations might be more tricky because the call site module associated with each overloaded name would need to be taken into account when inlining across module boundaries (ie a name used inside an inlined function needs to be resolved as if it had been used in the module where the function was defined not the module where the function is inlined). For example: module A where import Proposed.Control.Monad data T a = T a instance Monad T [-# INLINE foo #-} foo :: a - T a foo = return -- uses Monad class default -- which is inherited from the Applicative -- class default module B where import A import Proposed.Control.Monad instance Applicative T where return x = retB x bar :: T a bar = return 'q'-- would use (retB) zap :: T a zap = foo 'q'-- would use (return) from A A question is whether the extra difficulty in resolving overloadings (for human reader as well as complier) is worth the advantages of being able to get generated definitions for () for Applicative and (fmap) for Functor from a single instance decl for (Monad.=) etc. [Rearranged] The class aliases proposal lists several similar shortcomings of the current class system. http://repetae.net/john/recent/out/classalias.html IIUC the class alias proposal is about being able to group classes together and deal with them as a whole so similar issues of resolving overloadings arising from overlapping aliases/ explicit instance decls etc would arise (and I imagine the solutions would lie in similar directions). Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Composing functions with runST
Yitzchak Gale wrote: Can anyone explain the following behavior (GHCi 6.6): Prelude Control.Monad.ST runST (return 42) 42 Prelude Control.Monad.ST (runST . return) 42 interactive:1:9: Couldn't match expected type `forall s. ST s a' against inferred type `m a1' In the second argument of `(.)', namely `return' In the expression: (runST . return) 42 In the definition of `it': it = (runST . return) 42 Section 7.4.8 of GHC manual states that a type variable can't be instantiated with a forall type, though it doesn't give any explanation why. Hazarding a guess, I suggest it *might* be due to the fact that forall s. ST s a means forall s. (ST s a) whereas you'd need it to mean (forall s. ST s) a in order for it to unify with (m a). Just a guess - I'd be interested to know the real reason as well. Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Idiomatic Haskell equivalent of keyword argumentsto functions
Paul Moore wrote: I'm thinking around the design of a couple of things, and am hitting an issue which I know how I would solve in Python, but I'm not sure what a good idiomatic Haskell approach would be. The problem is that I am trying to write a function which takes a rather large number of arguments, many of which are optional (ie, have sensible defaults). There's an interesting solution to this in section 15 (starting page 53) of Magnus Carlsson and Thomas Hallgren's Fudgets thesis available online at: http://www.cs.chalmers.se/~hallgren/Thesis/ (Fudgets main page is at http://www.cs.chalmers.se/ComputingScience/Research/Functional/Fudgets/ ). Basically the idea is that for any function which takes lots of params, the params are gathered together into a datatype whose details are hidden from the user of the function. For each parameter, the user is given a function called a Customiser in the thesis, which takes a value of the hidden datatype and modifies it by setting the relevant parameter. Multiple params can therefore be specified by chaining Customisers together in any order with the usual function composition. The original function, instead of taking lots of params, now just takes a single parameter: a Customiser, which is used to turn the default params into the customised params. This is similar to the idea of using records but has the advantage that by judicious use of typeclasses of which the param data is an instance, you don't need to keep on inventing different names for the same thing (eg to specify colour for the background of a label control in a GUI or colour for a font you could use the name setColour in both cases). (A possible disadvantage is the overhead of having to create a whole new modified version of the parameter record for each Customiser in the composition so if efficiency were an issue you'd have to see if the compiler could inline the composition of the customiser functions to make it as efficient as the built in multiple field record update using rec{a=a', c=c'} syntax) To make things concrete, the example I'm really thinking of is a send an email function, which would take a subject, a body, a list of recipients, optional lists of cc and bcc recipients, an optional mailserver (default localhost), an optional port (default 25), and possibly optional authentication details. I found a couple of Haskell modules implementing a SMTP client, but they both just used a list of positional parameters, which I'm not really happy with. At the very least, I'd like to wrap them in a nicer interface for my code. -- hidden from clients data EmailParams = EmailParams { subject :: String , body :: String , recipients :: [Recipient] , cc :: [Recipient] , bcc :: [Recipient] , mailserver :: Mailserver , port :: Port , authentication :: Authentication } -- record syntax elided to save space defaultEmailParams = EmailParams [] [] [] defaultMailserver defaultPort defaultAuthentication --a Customiser visible to clients setSubject :: String - EmailParams - EmailParams setSubject s ep = ep{subject = s} -- etc send :: (EmailParams - EmailParams) - IO () send f = sendInternal (f defaultEmailParams) where sendInternal :: EmailParams - IO () sendInternal = ... -- In user code: main = send (setSubject Test . setBody A test email) Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Seeking advice on a style question
Steve Schafer wrote: In my text/graphics formatting work, I find myself doing a lot of pipeline processing, where a data structure will undergo a number of step-by-step transformations from input to output. For example, I have a function that looks like this (the names have been changed to protect the innocent--and to focus on the structure): process :: a - b - c - d - e process x1 x2 x3 x4 = let y01 = f01 x1 x2 x3; y02 = f02 x1; y03 = f03 y02; y04 = f04 y03; y05 = f05 x1 y01 y04; y06 = f06 x2 y05; (y07,y08) = f07 y01 y06; y09 = f08 y07; (y10,y11) = f09 x2 x4 y09 y08; y12 = f10 y10; y13 = f11 y12; y14 = f12 x1 x2 x3 y01 y13; y15 = f13 y14; y16 = f14 y15 y11 in y16 Disclaimer: just re-written by hand so needs double-checking before use: process x1 x2 x3 x4 = let y01 = f01 x1 x2 x3 (y07, y08) = f07 y01 (f06 x2 (f05 x1 y01 (f04 (f03 y02 (y10, y11) = f09 x2 x4 (f08 y07) y08 in f14 (f13 (f12 x1 x2 x3 y01 (f11 (f10 y10 y11 You can also make it look more like the diagram by using more indentation eg: process x1 x2 x3 x4 = let y01 = f01 x1 x2 x3 (y07, y08) = f07 y01 (f06 x2 (f05 x1 y01 (f04 (f03 y02 ... Best regards, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Versioning
Lennart Augustsson wrote: On Dec 21, 2006, at 15:53 , Neil Mitchell wrote: Hi there are really no choices for real development. many libraries, language extensions and techniques are for ghc only I develop everything in Hugs, including the Yhc compiler itself. Hugs is great. There are lots of extensions in GHC, but Haskell 98 is a perfectly useable language! I must second this opinion. There's this (false) perception that you need all kinds of extensions to make Haskell usable. It's simply not true. Certain extensions can make your life easier, but that's it. Well, FingerTrees for example, require MPTCs as in pushL :: Measured v a = a - FingerTree v a - FingerTree v a For any kind of object oriented programming you need existentials to separate the interface from the different concrete objects. Also in the code I've written I've often needed higher rank polymorphism and scoped type variables. Sure it's possible to use all kinds of horrific hacks to try and avoid the need for scoped type variables etc but why would anyone waste their time writing difficult obfuscated code when GHC has the perfect solution all ready to use. In other words, what on earth is good about gluing oneself to Haskell98? Life's moved on... Best regards, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Versioning
Neil Mitchell wrote: Hi In other words, what on earth is good about gluing oneself to Haskell98? Life's moved on... If you stick to Haskell 98 you can: * Convert your code to Clean (Hacle) * Debug it (Hat) * Run it in your browser (ycr2js) * Document it (Haddock) * Make a cross platform binary (yhc) * Get automatic suggestions (Dr Haskell) ... Sometimes you need a type extension, but if you don't, you do get benefits. True, though it would be even better if the usual extensions were more widely supported, though I suppose identifying what's useful and therefore worth supporting is the point of the Haskell Prime process. As an aside I've often thought it would be better if the various components of Haskell compilers/tools would be separated out so that people could effectively build their own compiler tailored more specifically for their needs. Ie lots of smaller projects each dealing with a particular phase of Haskell processing which would be joined together by standard APIs, so that someone could use the latest type system extensions with whole program optimization while someone else could use those same type extensions with a back end designed for graphical debugging etc, and also so that people just interested in developing whole program optimization (for example) wouldn't have to reinvent the ever-more-difficult wheel of lexing/parsing/typechecking/targeting multiple platforms... Best regards, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Stronger static types, was Re: [Haskell-cafe] Re: Versioning
Jacques Carette wrote: Yes, dependent types have a lot to do with all this. And I am an eager lurker of all this Epigram. Would it be possible to augment Haskell's type system so that it was the same as that used in Epigram? Epigram itself uses a novel 2d layout and a novel way of writing programs (by creating a proof interactively) but these seem orthogonal to the actual type system itself. Also, typing is not the only issue for compile time guarantees. Consider: data Dir = Left | Right | Up | Down deriving Eq -- Compiler can check the function is total foo :: Dir - String foo Left = Horizontal foo Right = Horizontal foo Up = Vertical foo Down = Vertical versus -- Less verbose but compiler can't look inside guards foo x | x == Left || x == Right = Horizontal foo x | x == Up || x == Down = Vertical versus something like: foo (Left || Right) = ... foo (Up || Down) = ... Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Shrinking the Prelude: The categorical approach
Imam Tashdid ul Alam wrote: hi guys, I was just wondering if anyone is interested is a quasi-project of rewriting the Prelude (only shrinking it as measured by the total number of names imported, read along...) the idea is (just to be substantially different in approach) to develop an alternate history of Haskell. take map for example, and fmap, I don't think they should be named different (fmap is ugly, not suggestive, and conceptually the same). mplus could be renamed (++) (they are conceptually the same I suggest that all functions in classes be given actual names and ASCII symbolic names could be defined outside the class as an additional convenience eg: class Monad m = MonadPlus m where mzero :: m a mplus :: m a - m a - m a (++) = mplus-- 'convenience' name I think people forget that ASCII symbol names which look intuitive to them when they are writing a library or paper, can be very confusing for people who need to use many libraries (with consequent explosion of obfuscatory symbols) in a project, look terrible when qualified, and make code difficult to read because of the need to find/remember precedences and associativity. (Note that Haddock does *not* supply this info, you need to look at the actual source code of the library to find it out.) , mzero looks odd, name it empty, or simply zero) What about (mempty) from Monoid or (empty) from Data.Sequence or Control.Applicative? Either these are in some way the same thing as mzero, or else they are different in which case either qualified imports would be needed everywhere (not necessarily a bad thing) or different names like the ones we already have, are needed. although I think concat should be replaced by msum (or the other way around preferably :) ? msum is a bad name) I am somewhat confused by join. concat seems to match join's type but I don't think the ideas coincide. and so on. in particular, we would want: * no backwards compatibility. the Prelude as is it, is good enough. we are defining a new module. Starting with a clean slate seems a good idea, especially to get rid of lispy names like (cons), (snoc), (null) and replace them with something self-explanatory like (pushL), (pushR), (isEmpty). * clean categorical hierarchy of type classes (category theorists wanted!) promoting uniformity. This would be great. However it is a question to me whether it is even possible to organize everything in a single hierarchy. Eg look at the problems with trying to reorganize Num, or standard OOP problems with hierarchies in general. Since there are multiple ways of looking at a domain, it is likely there will need to be multiple hierarchies which will probably not interact so well. * cleaner names. foldl1 means nothing. absolutely nothing. what's the 1 for? A while back I suggested using capital letters for suffix to distinguish the functionality (fold) from the variant (L == left). Perhaps (foldl1) could be renamed (foldLN) ie fold + left + non-empty or (foldLO) for fold + left + occupied. * our Prelude only contains typeclasses, datatypes, and functions of utmost conceptual (and semantic, such as error, undefined and seq) importance, everything else goes to other modules. our Prelude is not going to be a place for convenient declarations. * the suffix method of naming (liftM2) is considered messy. we would prefer a seperate module (promoting qualified import). In the particular case of *M functions, I quite like the existing naming since it's clear that it's a monadic function. However I'd agree that names like (newIORef) are an abomination, that should be replaced by (Ref.new). this is a fun project. we will not rewrite the Prelude, we'll merely rename it. I would suggest the name TheOtherPrelude to make our intentions clear. the conveniences (like concatMap) goes to TheOtherPrelude.Extension. I suggest we do it on the wiki. anyone interested just open a page with your name of choice. I am not doing it only because there's no point doing it if no one's interested. Good luck with this. For my own project, I re-implemented FingerTree's so I could use my preferred naming style (and also as an exercise following the excellent tutorial-style FingerTree paper), and wrote some trivial wrappers for a few other modules eg Data.IORef, Data.Unique so that I could use Ref.new, Unique.new etc.I think it would be quite a big task to refactor the entire code base according to a clean hierarchy of type classes, and also a task I can't really help with since I'm not familiar enough with category theory at present, but certainly it would be a worthwhile endeavour imho, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell Side Effect
Ashley Yakeley wrote: Since learning Haskell, I can now count in Spanish! See: one in Spanish, two in Spanish, three in Spanish, four in Spanish.. Is there a solution ie some concept C such that C Haskell C Spanish, somewhere? Thanks, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Class annotation on datatype ineffective in function
Reto Kramer wrote: The code below does not compile unless the bar function is annotated with a suitable constraint on the class of the formal parameter. class (C a) data (C foo) = XY foo = X foo | Y foo bar :: a - XY a bar aFoo = X aFoo As suggested, this works: bar :: (C a) = a - XY a Can someone explain to me why the compiler can not infer that a (in bar) must be (C a) from the bar result type XY a (by way of the C class provided for the datatype)? Hi Reto - If you'd not given any signature at all the compiler would have inferred the correct type for bar, but since you gave an explicit signature, the compiler had no option but to complain that you missed out the C a constraint. (ie if you decide to provide a signature you must give the full signature including constraints since the compiler won't add anything to them - partial signatures are not (yet) supported) Regards, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Showing the 1 element tuple
Neil Mitchell wrote: Hi, A weird question, what does the 1 element tuple look like? () -- 0 element tuple (,) a b -- 2 element tuple (,,) a b c -- 3 element tuple () a - meaningless (a) - a in brackets GHC has the 1 element unboxed tuple, (# a #), and all the other sizes unboxed as well, but how would you visually represent the 1 element boxed tuple? Tuples represent dimensionality therefore a 1-element tuple is just a 1-dimensional value ie the value itself hence a == (a) == ((a)) == (((a))) == ... Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell] ANNOUNCE: Phooey -- a Functional UI library for Haskell
From: Conal Elliott To: haskell@haskell.org Sent: Tuesday, December 12, 2006 7:17 AM GUIs are usually programmed in an unnatural style, in that implementation dependencies are inverted, relative to logical dependencies. This reversal results directly from the imperative orientation of most GUI libraries. While outputs depend on inputs from a user and semantic point of view, the imperative approach imposes an implementation dependence of inputs on outputs. Hi, This looks really interesting, but I'm struggling to understand what you mean by reversal. Can you elaborate on what you mean by the imperative approach imposes an implementation dependence of inputs on outputs. In the model-view-controller pattern for example, I see no such reversal. Also, suppose you have a gui consisting of an edit widget such that when the user types something it gets lexed, parsed, and fontified as a Haskell program, ie from the user's point of view the widget maintains a syntax highlighted view of the code which is continuously updated. Would your system do the lexing/parsing for every key that was pressed or only once, when the widget needs to be re-rendered (a typical gui for Windows would only propagate changes and re-draw the gui (ie lex/parse/fontify) when there are no event messages pending)? In other words, does your system solve the problem of automatic caching of updates that would be solved in the imperative setting by the (admittedly rather messy) waiting for nothing else happening? Regards, Brian. -- http://www.metamilk.com ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
[Haskell-cafe] Re: [Haskell] ANNOUNCE: Phooey -- a Functional UI library for Haskell
Brian Hulley wrote: Conal Elliott wrote: GUIs are usually programmed in an unnatural style, in that ... Also, suppose you have a gui consisting of an edit widget such that when the user types something it gets lexed, parsed, and fontified as a Haskell program, ie from the user's point of view the widget maintains a syntax highlighted view of the code which is continuously updated. Would your system do the lexing/parsing for every key that was pressed or only once, when the widget needs to be re-rendered (a typical gui for Windows would only propagate changes and re-draw the gui (ie lex/parse/fontify) when there are no event messages pending)? Thinking about this more, a better example would be a gui with 2 widgets: an edit widget to type in code and a list widget which displays a list of top level functions defined in that code. (The code could be Haskell or some simple toy language.) Then the question becomes: how to set things up such that the code in the edit widget is only parsed when the list widget (and/or edit widget) is asked to render it's contents rather than every time the user presses a key. I think perhaps the problem would be solved by the edit widget passing a lazy parse tree (ie an expression evaluating to the parse tree) to the list widget. But an interesting thing is if you compare this to imperative guis, in the functional gui each widget passes lazy expressions eagerly whereas in imperative guis each widget passes eagerly evaluated expressions lazily ie functional is push messages whereas imperative is pull changes when I'm asked to pick or render something etc and I'm dirty. (Have I got this wrong?) I imagine that the overhead of eager passing in the functional gui is a small price to pay for the ease of using a functional gui, since the important thing is that in both guis, the hard work of parsing the code in the edit buffer would only be done on demand, unless I'm much mistaken. If you're still thinking of examples for your paper it would also be really great to see how you'd create a widget that displays the result of another process (eg a window that displays the output as ghc compiles a program) or some other example of how to use the IO monad inside a widget for those unfamiliar with combining arrows with monads. It would also be useful to know more about the relationship between the functional gui and WxWidgets to see what characteristics an imperative gui toolkit must have in order to be usable with it. (Like the extremely useful discussion of low level details in the Fudgets thesis.) Best regards, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Aim Of Haskell
Kirsten Chevalier wrote: since it's not as if anyone programs in Pascal anymore. Yet I'm sure most people who did a computer science degree some decades ago remember the old joke about passing things by name or value for what it's Wirth... :-) Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functional GUI combinators for arbitrary graphs of components?
Taral wrote: On 12/1/06, Brian Hulley [EMAIL PROTECTED] wrote: This problem is so general (ie converting a cyclic graph into an expression tree such that each node appears no more than once) that I'm sure someone somewhere must already have determined whether or not there can be a solution, though I don't know where to look or what to search for. I suggest you check the Functional Graph Library (FGL). It's shipped as part of GHC. Thanks for the suggestion. FGL itself (afaics) doesn't seem to have what I was looking for but graph algorithm would be a good place to start looking. Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functional GUI combinators for arbitrary graphs ofcomponents?
Paul Hudak wrote: Brian Hulley wrote: Anyway to get to my point, though all this sounds great, I'm wondering how to construct an arbitrary graph of Fudgets just from a fixed set of combinators, such that each Fudget (node in the graph) is only mentioned once in the expression. To simplify the question, If you consider just Dags, I believe that this question is equivalent to asking what set of combinators will allow you to create an arbitrary composition of functions that allow sharing inputs and returning multiple results. And I think that one answer to that is the set of combinators that make up the Arrow class. If you want to include recursion (i.e. cycles), then you'd have to throw in ArrowLoop (although that might only provide a nested form of cycles). It's in this sense that Fudgets is analogous to Fruit. Thanks. Actually thinking more about it I've probably missed the point that for a compositional GUI there's no need for a general graph, since each view/controller of the underlying model could be encapsulated as a single widget (eg fudget or signal transformer) which could be connected to the model via a loop which exposes only the model (thus allowing other views to be added later). Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Strange type behavior in GHCi 6.4.2
Grady Lemoine wrote: f x = x^3 f' = snd . (evalDeriv f) When I load this in GHCi, I get: *Main :t f f :: (Num a) = a - a *Main :t snd . (evalDeriv f) snd . (evalDeriv f) :: (Num a, Num (Dual a)) = a - a *Main :t f' f' :: Integer - Integer Why is the type of f' Integer - Integer, especially when the type of the expression it's defined as is more general? Is this something I'm not understanding about Haskell, or is it more to do with GHC 6.4.2 specifically? This is the monomorphism restriction, which basically says that any binding which just has a single variable on the left of the '=' is artificially forced to be monomorphic (unless you've given it an explicit type signature) eg: f = \x - x + 1-- Integer - Integer whereas f x = x + 1-- Num a = a - a The reason for this is that if you have something like: let x = e in (x,x) you often expect the expression (e) to be evaluated at most once, and shared by the two components of the tuple. However if there were no monomorphism restriction, then (x) could be polymorphic hence (e) would have to be evaluated twice (once for each overloading, even if the result tuple is fed to another function which expects both elements to have the same type) which would make programs run slower than the programmer expected. I couldn't find any page on the wiki about this, but there's lots of stuff scattered around on the web, and endless discussions in the Haskell mailing lists which make entertaining reading ;-) (The MR is controversial - see http://hackage.haskell.org/trac/haskell-prime/wiki/MonomorphismRestriction for the latest on what might happen to it in future versions of Haskell.) Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Functional GUI combinators for arbitrary graphs of components?
Hi, I've been looking at the Fudgets research (http://www.cs.chalmers.se/ComputingScience/Research/Functional/Fudgets/ ) as an example of a purely functional gui. Afaiu a brief summary is that a Fudget can represent a GUI widget or some other object, which can have some internal state, and which receives and passes messages to the other Fudgets it is connected to. Fudgets are connected to each other by combinators eg: second == first-- sequential (first sends messages to second) a * b -- parallel There is a continuation passing implementation such that the messages are passed and internal states of Fudgets are updated (by replacing each fudget with an updated fudget) as these expressions are evaluated hence the message passing and maintenance of state doesn't involve any IORefs though interaction with external devices such as the OS uses IO. Anyway to get to my point, though all this sounds great, I'm wondering how to construct an arbitrary graph of Fudgets just from a fixed set of combinators, such that each Fudget (node in the graph) is only mentioned once in the expression. To simplify the question, assume we have the following data structure to describe the desired graph: data LinkDesc a = Series a a | Broadcast a [a] | Merge [a] a type GraphDesc a = [LinkDesc a] and a function to compute a combined object (eg Fudget) corresponding to an arbitrary graph would be: mkObj :: Ord label = Map label Obj - GraphDesc label - Obj mkObj = -- ??? The result of mkObj will be some expression, composed from a finite set of combinators applied to the named objects, but with the all important property that each named object appears no more than once in the expression (this is what allows Fudgets to correspond to notional objects which maintain internal state - during evaluation each fudget gets replaced by an updated fudget hence can only appear once in the whole expression). As a very simple example using existing Fudgets combinators, type Map label value = [(label, value)] mkObj [(A, objA), (B, objB), (C, objC)] [Series A B, Series B C] ===objC == objB == objA and mkObj [(A, objA), (B, objB), (C, objC)] [Broadcast A [B, C]] === (objB * objC) == objA However: mkObj [(A, objA), (B, objB), (C, objC), (D, objD)] [Broadcast A [B, C], Series B D, Series A D] === ??? The Fudgets library provides many combinators eg for looping, but even so, I don't think there are sufficient combinators to express the above graph (though possibly extra nodes and tagging/untagging would solve this example), or more heavily connected graphs such as: [Series A B, Series B C, Series C D, Series D B, Series C A] This problem is so general (ie converting a cyclic graph into an expression tree such that each node appears no more than once) that I'm sure someone somewhere must already have determined whether or not there can be a solution, though I don't know where to look or what to search for. Any ideas? Thanks, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functional GUI combinators for arbitrary graphs ofcomponents?
Brian Hulley wrote: Anyway to get to my point, though all this sounds great, I'm wondering how to construct an arbitrary graph of Fudgets just from a fixed set of combinators, such that each Fudget (node in the graph) is only mentioned once in the expression. To simplify the question, assume we have the following data structure to describe the desired graph: data LinkDesc a = Series a a | Broadcast a [a] | Merge [a] a type GraphDesc a = [LinkDesc a] The above is more complicated than necessary. The problem can be captured by: type GraphDesc a = [(a,a)] Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Haskell] Defining Cg, HLSL style vectors in Haskell
Slavomir Kaslev wrote: I have to define a couple of float2, float3, float4 Cg, HLSL style vectors in Haskell. At first I was tempted to make them instances of Num, Floating, RealFrac, etc. but some of the functions defined in those classes have no sense for vectors. I'd suggest that this implies that these classes are not suitable for Vectors. One such example is signum from class Num. There are several workarounds for this. One may come up with some meaning for vectors of such functions, for example: instance Num Float3 where . signum a | a == Float3 0 0 0 = 0 | otherwise = 1 This looks a bit unnatural. Also, testing equality of Floats is not generally recommended. [snip] I know that I can scrap all those Num, Floating, RealFrac, etc. classes and define class Vector from scratch, but I really don't want to come up and use different names for +, -, etc. that will bloat the code. While it may be tempting to want to use symbolic operators like + and -, these quickly become very confusing when more distinctions need to be made (eg between cross product, dot product, and scaling, or between transforming a position versus transforming a direction) so I'd argue that for readability descriptive names are better than symbols: class Num a = Vector v a where plus :: v a - v a - v a minus :: v a - v a - v a cross :: v a - v a - v a dot :: v a - v a - a scale :: a - v a - v a magSquared :: v a - a class Num a = Transform mat vec a where transformPosition :: mat a - vec a - vec a transformDirection :: mat a - vec a - vec a instance Num a = Transform Mat44 Vec4 a where -- ... If you're doing matrix transformations, you might also like to consider using separate PositionN and DirectionN types instead of VecN to make use of the type system to catch some math bugs but I haven't looked into this myself yet so I don't know whether this would be practical or not. Best regards, Brian. -- http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Passing arrays between Haskell and C without overhead
Hi, For a 3d graphics library, I'd like to have a 4x4 matrix of floats which I can pass from Haskell to C without having to copy all 16 floats each time, something like: data Mat44f = Mat44f Float# Float# ... Float# foreign import ccall c_setWorldTransform :: Ptr Mat44f - IO () setWorldTransform :: Mat44f - IO () setWorldTransform mat = withSafePtr mat c_setWorldTransform where withSafePtr :: a - (Ptr a - IO b) - IO b would supply a pointer directly to the Haskell heap representation of (a) and would ensure that (a) doesn't get garbage collected until the IO action is completed. (Note that this is not the same as Foreign.Marshal.Utils.with, which uses alloca and poke to copy the matrix - I'm trying to avoid this overhead of copying.) However there is no such function afaics so the only solutions at present seem to be to either make Mat44f an instance of Storable and use alloca (which involves copying all 16 floats just so that C can read it even though I'd expect the heap representation to already be identical since there is only one constructor and all fields are unboxed) or else pass the 16 floats individually by: foreign import ccall c_SetWorldTransform' :: Float# - Float# - ... - Float# - IO () setWorldTransform (Mat44f m11 m12 m13 m14 ... m44) = c_SetWorldTransform' m11 m12 m13 ... m44 In this second case the C function will have to manually put these 16 floats back into an array so that it will have a pointer to a temporary array of 16 floats to use internally (eg to pass to the DirectX api which will then make its own copy of it), so in both cases there is a wasteful deconstruction then reconstruction of the original array of 16 floats stored on the Haskell heap. Similar problems arise when trying to pass an array from C back to Haskell, but in this case it's clear some copying will be needed so that one ends up with a value stored on the Haskell heap - the double copy problem only arises in the direction from Haskell to C. I've also thought about just implementing all the math functions in C and using mallocForeignPtrArray so that the data type would be: newtype Mat44f = Mat44f (ForeignPtr CFloat) While this would make passing between C and Haskell very fast, it seems a pity to have to sacrifice the ability to code the math ops directly in Haskell in a functional style with all the attendant optimizations one could expect from GHC (using ForeignPtr requires unsafePerformIO, withForeignPtr, and lots and lots of peek/pokeElemOff's in a monadic style - rather gross compared to pattern matching etc) So my questions are: 1) Is there any reason why there can't be a function (withSafePtr) to avoid all this marshalling overhead when we know (or specify via a pragma) that Haskell stores the data already in a form compatible with C, or is there some other way to represent a 4x4 matrix such that it can be manipulated in Haskell and passed without overhead to C? 2) Does withSafePtr already exist somewhere? 3) Would it be a good idea to make Storable one of the classes which can be automatically derived? Thanks, Brian. -- http://www.metamilk.com ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Passing arrays between Haskell and C without overhead
Bulat Ziganshin wrote: Hello Brian, Sunday, November 26, 2006, 5:34:51 PM, you wrote: For a 3d graphics library, I'd like to have a 4x4 matrix of floats which I can pass from Haskell to C without having to copy all 16 floats each time, something like: http://haskell.org/haskellwiki/Modern_array_libraries you should use StorableArray. also, i suggest you to use ghc 6.6 because it has much faster foreign ptrs implementation. you may also consider using my ArrayRef lib, although from that you said i don't see that you will get any advantages from this Hi Bulat - Thanks for the suggestion and the link to that page - the info on it is very useful, Brian. -- http://www.metamilk.com ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
[Haskell-cafe] Why instances can't be hidden (was: non-total operator precedence order)
Benjamin Franksen wrote: Henning Thielemann wrote: On Fri, 10 Nov 2006, Benjamin Franksen wrote: Although one could view this as a bug in the offending module it makes me somewhat uneasy that one additional import can have such a drastic effect on the code in a module /even if you don't use anything from that module/. It's the same as with instance declarations, isn't it? I don't want to defend the problems arising with todays anonymous instance declarations, Right. However, with instances I can imagine solutions that avoid naming them, that is, I could imagine to write something like select instance C T1 T2 ... Tn from module M or import M hiding (instance C T1 T2 ... Tn, ) Such a feature could prove extremely useful in practice. Disclaimer: I am almost sure that there is something I have overlooked that makes such a simple solution impossible, otherwise it would have been proposed and implemented long ago... I think the reason you can't do this kind of thing is that within any set of modules that is compiled at the same time, anywhere in any of these modules, if you have a type T that's an instance of class C, then all occurrences of C T must refer to the exact same instance declaration or else things would get totally messed up when/if the compiler did whole program optimization. In other words, the instances are actually properties of the type(s) themselves so allowing different modules to see different implementations of the instances would break the conceptual merging of modules (modulo renaming) that occurs at compile time. Regards, Brian. -- Logic empowers us and Love gives us purpose. Yet still phantoms restless for eras long past, congealed in the present in unthought forms, strive mightily unseen to destroy us. http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: ghc 6.6 for Windows crashes my program on exit
Brian Hulley wrote: Hi, Has anyone else come across this crash with ghc 6.6 on Windows? The thread 'Win32 Thread' (0x5c8) has exited with code 0 (0x0). First-chance exception at 0x7c90eb74 in main.exe: 0xC008: An invalid HANDLE was specified. Unhandled exception at 0x7c90eb74 in main.exe: 0xC008: An invalid HANDLE was specified. Actually this behaviour happens even with the trivial program main = return () so I've submitted a bug report at http://hackage.haskell.org/trac/ghc/ticket/942 Best regards, Brian. -- Logic empowers us and Love gives us purpose. Yet still phantoms restless for eras long past, congealed in the present in unthought forms, strive mightily unseen to destroy us. http://www.metamilk.com ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: [Haskell-cafe] Automatic fixity allocation for symbolic operators
Jim Apple wrote: On 10/14/06, Brian Hulley [EMAIL PROTECTED] wrote: User defined fixities are an enormous problem for an interactive editor This is the second or third time you've proposed a language change based on the editor you're writing. I don't think this is a fruitful avenue. Bertram Felgenhauer wrote: Brian Hulley wrote: infixr 9 .!! 99.9 Ouch. As far as editors go I have little sympathy. Nicolas Frisby wrote: I think it's unreasonable to tie programmers' hands for the sake of off-loading rather trivial tasks to editors. J. Garrett Morris wrote: On 10/14/06, Nicolas Frisby [EMAIL PROTECTED] wrote: Perhaps the editor could assume a default precedence ... I agree that changing the language in such an unintuitive way - breaking existing code in the process - to suit an editor is counterproductive and ridiculous. I feel that the example I used of an interactive editor has somewhat eclipsed the purpose of my post, which was basically to see if there is some way to arrive at an agreed association of operator precedences with symbolic ops such that this would include the current Prelude operators and have some kind of intuitive extension to all other possible symbolic ops which would respect one's expectations that * and + should be similar to * and + in terms of relative precedence and absolute associativity. After all, if a library writer decided to make * bind more loosely than + one might justifiably be frustrated at the apparent inconsistency therefore why not just make all this systematic and fixed down to remove these problems? I had thought perhaps someone might have already made such a global operator table suitable for functional programming, or some suitable algorithm hence the inclusion of my first stumbling attempt at one to try and set the ball rolling and at least save someone else several hours of hard work going down the same dead end if such it is. Jim Apple wrote: There are three ways to change Haskell's lexical structure: 1. DIY on an open-source compiler/interpreter of your choice. 2. Write your own compiler/interpreter. 3. Get the change into Haskell''. If the Haskell'' procedure is like the Haskell' procedure, you'll have to do 1 or 2 before you do 3. It's possible that you will convince someone that your syntax changes are worth doing, and that this person will do step 1 or step 2 for you, but I don't think so. I haven't done the research myself, but I think if you look at the source control logs for Your Favorite Haskell Compiler/interpreter and the HCAR, you will find very few commits/projects devoted to syntax. I think this is because Haskellers are much more interested in semantics. Afaiu the whole concept of type classes arose because of the desire to avoid having to think up different names for related functions and MPTCs were suggested by the syntax for single parameter TCs (though I can't remember the reference where I think I remember reading this latter point). Proposing changes that break existing code or segment the Haskell code base just doesn't seem like a win. Since all syntactic and many semantic changes necessarily break existing code or segment the code base this would seem to imply that the language should not be changed at all or that everything must be backwards compatible, so that we have to drag the Achilles heel of original mistakes around for all eternity. I'd have thought a solution would be to just use a tool to automatically convert existing code to whatever new syntax is found to be better, thus allowing the language to be gradually perfected as more and more issues are brought to light. Still I agree with you that a more sensible approach in terms of someone like me writing an editor is simply for me to take Haskell as an inspiration and incorporate my ideas in it so that any changes can later be seen in relation to a (hopefully facilitated and enjoyable) programming experience rather than trying to share my ideas piecemeal and insufficiently contextualized as they arise. Thanks to all who replied, Brian. -- Logic empowers us and Love gives us purpose. Yet still phantoms restless for eras long past, congealed in the present in unthought forms, strive mightily unseen to destroy us. http://www.metamilk.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe