Re: [Haskell-cafe] Re: Why binding to existing widget toolkits doesn't make any sense
>> My primary claim for success is that the >> representation of Picture in Haven type checks and doesn't appeal to >> IO; IO only creeps in when we attempt to render a Picture. > > You did something much more meaningful to me that what you say here. > Thanks. ;-) > [...] > > I think what you did in Haven (based on memories of our conversations at the > time and looking at your slides just now) is substantively different. You > gave precise, complete, and tractably simple *denotation* to your types. > Complete enough to define the correctness of the rendering process. > >> Does the Haven API live up to your goal of semantic purity for a >> vector graphics library? If not, where specifically does it fall short? > > Yes, if my understanding about denotational precision and completeness is > correct. Is it? > Yes and no. "Yes" in the sense that every type in Haven had a simple definition using Haskell's type system and I used these types to specify signatures of a set of functions for 2D geometry that was relatively complete. "No" in the sense that I never bothered to implement the various geometric functions directly in Haskell; I depended on the underlying implementation to do so. For simple things like points, lines and affine transforms I don't think this should be too controversial, but it's a bit less clear for clipping and constructive area geometry on complicated Bezier paths. From a library user's point of view there isn't much distinction between what I did and a pure implementation, but I can't really claim it's a rigorous or complete semantics without a pure reference implementation, and there's obviously no way to prove claims such as "Shapes form a monoid" without giving a direct definition of the composition and clipping operators. -Antony ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Why binding to existing widget toolkits doesn't make any sense
Hi Conal, On Sat, Jan 31, 2009 at 12:10 AM, Conal Elliott wrote: >> Hopefully some enterprising Haskell hacker will wrap Cairo in a nice >> purely functional API. > > Jefferson Heard is working on such a thing, called Hieroglyph. [...] > > In the process, I realized more clearly that the *very goal* of making a > purely functional wrapper around an imperative library leads to muddled > thinking. It's easy to hide the IO without really eliminating it from the > semantics, especially if the goal is defined in terms of an IO-based > library. Much harder, and I think much more rewarding, is to design > semantically, from the ground up, and then figure out how to implement the > elegant semantics with the odds & ends at hand (like Cairo, OpenGL, GPU > architectures, ...). Exciting! I was very much trying to achieve this with Haven back in 2002: http://www.haskell.org/haven As the slides on that page state pretty explicitly, I tried to focus on the semantics and to design a purely functional representation of a vector graphics scene that was not tied to any particular implementation. My primary claim for success is that the representation of Picture in Haven type checks and doesn't appeal to IO; IO only creeps in when we attempt to render a Picture. Does the Haven API live up to your goal of semantic purity for a vector graphics library? If not, where specifically does it fall short? I look forward to seeing and reading more about Hieroglyph. The typography and visual presentation of Jefferson's online booklet looks fantastic. A high quality, purely functional vector graphics API for Haskell with portable and robust implementations will be a great thing for the Haskell world. Regards, -Antony ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Why binding to existing widget toolkits doesn't make any sense
On Fri, Jan 30, 2009 at 4:25 PM, Bryan O'Sullivan wrote: > On Fri, Jan 30, 2009 at 1:11 PM, Antony Courtney > wrote: >> >> A 2-D vector graphics library such as Java2D ( or Quartz on OS/X or >> GDI+ on Windows ) supports things like computing tight bounding >> rectangles for arbitrary shapes, hit testing for determining whether a >> point is inside or outside a shape and constructive area geometry for >> shape compositing and clipping without dropping down to a raster >> representation. > > These are the kinds of capabilities provided by Cairo, which is very > pleasant to use (PDF-style imaging model) and quite portable. There are > already Cairo bindings provided by gtk2hs, too. > Hi Bryan, Nice to hear from you! Been a while... Just had a quick look and it does indeed appear that Cairo now supports some of the features I mention above (bounds calculations and hit testing). Cairo has clearly come a long way from when I was last working on Fruit and Haven in 2003/2004; back then it looked like it only provided a way to render or rasterize vector graphics on to bitmap surfaces and not much else. It's not clear to me if the Cairo API in its current form supports vector-level clipping or constructive area geometry, and it looks like the API is still pretty render-centric (e.g. is it possible to obtain the vector representation of rendering text in a particular font?). That might make it challenging to use Cairo for something like the Haven API, but maybe one can live without that level of generality. In any case: delighted to see progress on this front! Hopefully some enterprising Haskell hacker will wrap Cairo in a nice purely functional API. -Antony ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Why binding to existing widget toolkits doesn't make any sense
On Fri, Jan 30, 2009 at 3:50 PM, Achim Schneider wrote: > Antony Courtney wrote: > >> One issue I think you may encounter, though, is that last time I >> looked, there was still no high-quality, widely available >> cross-platform 2-D vector graphics library in C or C++! [...] >> > Xrender. It appears to map exceptionally well onto FP, is available > everywhere X is available (that includes Windoze and OS X) and usually > is heavily hardware-accelerated. Additionally, we already have a pure > Haskell implementation of the client-side protocol included in XHB. > According to Wikipedia: The X Rendering Extension (Render or XRender) is an X Window System extension to implement Porter-Duff image compositing in the X server. Porter-Duff image compositing is cool and useful, but it's at a much lower level than what I meant by 2-D vector graphics library. A 2-D vector graphics library such as Java2D ( or Quartz on OS/X or GDI+ on Windows ) supports things like computing tight bounding rectangles for arbitrary shapes, hit testing for determining whether a point is inside or outside a shape and constructive area geometry for shape compositing and clipping without dropping down to a raster representation. Pretty clear how to build a 2-D Scenegraph library like Piccolo on top of Java2D or Quartz or GDI+; much less clear to me how to build something like that directly on top of XRender. -Antony ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Why binding to existing widget toolkits doesn't make any sense
On Fri, Jan 30, 2009 at 2:21 AM, Evan Laforge wrote: >> Conal> As Meister Eckhart said, "Only the hand that erases can write the >> Conal> true thing." >> >> Nicely said... >> >> I'm sure you're not the only one desiring to write GUI in "genuinely >> functional" toolkit, but, being realistic and considering how many people >> are working on bindings for those "legacy libraries", I doubt we'll see >> something written from the scratch and usable for "Real World Haskell" >> soon ;) > > I'm vaguely aware that there has been a line of functional-style > widget libraries, from fudgets down to developments like arrows and > FRP and the various libraries built on that. The fact that the > libraries have continued to be research projects and beget further > research projects implies that they've had some critical flaws that > needed further research. Is there a description somewhere of what the > critical flaws have been and are, and what the current problems are to > solve before we can finally have a practical declarative and > compositional UI library? Here is a message I sent to Conal and the yampa-users list about a year ago with my thoughts on this very topic. Hope this helps. Kind Regards, -Antony Date: Fri, 22 Feb 2008 09:35:48 -0500 From: "Antony Courtney" To: "Conal Elliott" Subject: Re: Fruit Cc: Yampa-Users Hi Conal (and Paul and Henrik and everyone else!), Apologies for the delay in replying. Paul is quite right about my day job keeping me quite busy, although I've been enjoying watching the discussion. I think there are several reasons that Fruit never really caught on. First and foremost, Fruit never provided anything close to the full suite of GUI components found in modern UI toolkits (buttons, sliders, scrollbars, check-boxes, text fields, combo boxes, split panes, tabs, menus, toolbars, etc. etc.). I never got much further than implementing labels, buttons, text fields and maybe one or two other components. This wasn't quite as limiting as one might think as Fruit subsumed everything that was possible to do in Fran and had a very powerful vector graphics library underneath (Haven) so one could use Fruit to implement quite sophisticated interactive animations and combine them with the library of other GUI components. But one couldn't realistically expect to download and install Fruit and just start using it to write the next great full-fledged GUI app. in Haskell. This is related to the second reason Fruit didn't catch on, which is that Fruit was built directly on an interactive graphics library, not a standard GUI toolkit. I think that this was the right first step for our research goals of giving a rigorous answer to the question of "What is a formal model of a GUI?". But from both a pragmatic and research point of view, the next interesting research problem to solve would be: "How can we present the Fruit programming interface (which offers a clean, simple, pure semantic model of a GUI), but implement the individual GUI components using a standard GUI toolkit?". This is actually an interesting implementation challenge since Yampa's switching and dynamics collections mean that absolutely anything can happen to the widget hierarchy from one time step to the next. You really, really don't want to destroy and rebuild the entire widget hierarchy of the application at every time step, so figuring out how to do some kind of sample-to-sample differencing of the widget hierarchy would be essential. It's not obvious how to do this, which is probably why FranTk and wxFruit took a bit more of a pragmatic approach and exposed bits of the imperative programming model of the underlying toolkit for widget creation and destruction. Another important point is that even the bits of fruit that were implemented involved a number of different dependent parts, so it was always a bit more work to download and install than I would have liked. I was hell-bent on using a vector graphics library as the foundation. Unfortunately there was no widely-available cross-platform vector graphics library implemented in C. So I chose to use Java2D, which meant that I had to build my own system for Haskell/Java interoperability (GCJNI, later hsjni) and a Haskell vector graphics library (Haven) on top of that. So if one wanted to play with fruit, it was necessary to download and install Java, gcjni, haven, yampa and fruit. And in the early days one also had to grab greencard and the arrows preprocessor! I think we did a reasonable job of packaging these given the severe limits of Haskell packaging and build tools at the time, but it was a ton of work and still never made it easy enough for others to experiment casually. Apart from the practicalities of the impl
Re: [Haskell-cafe] Problems with building GCJNI 1.2
Hi, Sorry for not jumping in on this discussion sooner. I am the author of GCJNI. GCJNI was developed back when Hugs was the dominant Haskell implementation and GreenCard was the easiest/best way to do foreign language bindings for Haskell because the FFI proposal was still in the formative stages. These days, the Haskell FFI addendum is stable and widely implemented, ghc has become much more widely available and easy to install and use, and (without wishing to sound harsh), GreenCard's FFI code generator was broken and useless the last time I tried to use it (a few years ago). I actually ported GCJNI to the Haskell FFI a few years ago, getting rid of ALL use of GreenCard. I used ghc's 'hsc2hs' tool to help with the marshalling, and made no attempt to port to hugs. I called this newer system 'hsjni'. It worked very well for my needs (using the Java2D rendering engine as the back-end for a prototype Haskell GUI system). I never released hsjni simply due to lack of time while finishing my thesis. I invested a little effort in trying to test hsjni with the latest JDK and get a release together in December, but it got snagged on a silly little bug in hsc2hs's handling of paths which have embedded spaces. A minor bug, to be sure, but since the default installation location for the JDK under Windows is under "C:\Program Files", the bug meant hsjni couldn't work out-of-the-box for the most common installation of the prerequisites. Simon Marlow has since fixed this bug in CVS head; I'm just waiting for the next release of ghc with this fix available before I try again. If you think you'd be interested in having a shot at building 'hsjni' (or you are interested in maintaining it), let me know, and I'll make the sources available for you. Caveat is that I haven't tested it since JDK 1.3, because of this hsc2hs issue. My appologies for not mentioning any of the above on the GCJNI web page. Hopefully the whole GCJNI release and web pages can be deprecated soon, with hsjni offered in its place. Kind Regards, -Antony -- Antony Courtneyemail: [EMAIL PROTECTED] New York, NY WWW: http://www.apocalypse.org/~antony ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Problems with building GCJNI 1.2
Hi, Sorry for not jumping in on this discussion sooner. I am the author of GCJNI. GCJNI was developed back when Hugs was the dominant Haskell implementation and GreenCard was the easiest/best way to do foreign language bindings for Haskell because the FFI proposal was still in the formative stages. These days, the Haskell FFI addendum is stable and widely implemented, ghc has become much more widely available and easy to install and use, and (without wishing to sound harsh), GreenCard's FFI code generator was broken and useless the last time I tried to use it (a few years ago). I actually ported GCJNI to the Haskell FFI a few years ago, getting rid of ALL use of GreenCard. I used ghc's 'hsc2hs' tool to help with the marshalling, and made no attempt to port to hugs. I called this newer system 'hsjni', but never released it due simply to lack of time while finishing my thesis. I invested a little effort in trying to test hsjni with the latest JDK and get a release together in December, but it got snagged on a silly little bug in hsc2hs's handling of paths which have embedded spaces. Simon Marlow has since fixed this bug in CVS head; I'm just waiting for the next release of ghc with this fix available before I try again. If you think you'd be interested in having a shot at building 'hsjni' (or you are interested in maintaining it), let me know, and I'll make the sources available for you. Caveat is that I haven't tested it since JDK 1.3, because of this hsc2hs issue. One can easily work around the hsc2hs path handling issue by installing the latest JDK in a location without a space in the filename; but since the default install location under Windows is under "C:\Program Files", I wasn't interested in shipping a release that wouldn't work with the most common default case. Please accept my sincere appology for not mentioning any of the above on the GCJNI web page. Hopefully it will just all be replaced with hsjni in the near future. Kind Regards, -Antony On Fri, 18 Feb 2005 20:45:14 +0100, Lemmih <[EMAIL PROTECTED]> wrote: > On Fri, 18 Feb 2005 20:37:35 +0100, Dmitri Pissarenko > <[EMAIL PROTECTED]> wrote: > > >>>Did you import Foreign.GreenCard? > > > > Now, I replaced "import StdDIS" by "import Foreign.GreenCard". > > The library apparently wasn't designed for newer versions of GreenCard > and it may be too old to fix easily. > > -- > Friendly, > Lemmih > ___ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Yet Another Monad Tutorial
Peter G. Hancock wrote: Jeff Newbern wrote (on Tue, 12 Aug 2003 at 17:20): ? > The functions exported from the IO module do not > perform I/O themselves. They return I/O actions, which describe an I/O > operation to be performed. The I/O actions are combined within the IO > monad (in a purely functional manner) to create more complex I/O > actions, resulting in the final I/O action that is the main value of the > program. The result of the Haskell compiler is an executable function > incorporating the main I/O action. Executing the program "applies" this > ultimate I/O action to the outside world to produce a new state of the > world. That seems to me the wrong thing to say. There is no application. Whether or not the word is put in quotes, it is something involving a function and an argument. An IO action is not a function. So then, in your view, what *is* an IO action? One conceptual model is that an IO action with type (IO a) denotes a function of type World -> (World,a). Given that model, "applying" an IO action to the external world seems like a perfectly reasonable account of executing such an action. -antony -- Antony Courtney Grad. Student, Dept. of Computer Science, Yale University [EMAIL PROTECTED] http://www.apocalypse.org/pub/u/antony ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: idiom for producing comma-seperated lists?
Ketil Z. Malde wrote: Antony Courtney <[EMAIL PROTECTED]> writes: -- Example: format a list of strings, using a comma as a seperator: mkSepStr :: [String] -> String mkSepStr xs = foldrs (\x s -> x ++ ", " ++ s) "" xs t0 = mkSepStr [] -- ==> "" t1 = mkSepStr ["hello"]-- ==> "hello" t2 = mkSepStr ["10","20","30"] -- ==> "10, 20, 30" What do the rest of you do to solve this particular problem? Uh, concat and intersperse? Yep, that'll do the trick. Thanks for all the lightnin-fast responses. Appologies for overlooking this! -antony -- Antony Courtney Grad. Student, Dept. of Computer Science, Yale University [EMAIL PROTECTED] http://www.apocalypse.org/pub/u/antony ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
idiom for producing comma-seperated lists?
I often need to format a list of strings using some character as a *seperator* rather than a terminator for the items. Is there some simple combinator or idiom from the Prelude or standard libraries that could be used for this purpose? I ended up defining my own variation on foldr1 to solve this (code below), but I'd be much happier using some more standard solution: -- A variation on foldr1 that takes an extra argument to be returned if -- the list is empty. foldrs :: (a -> a -> a) -> a -> [a] -> a foldrs f z [] = z foldrs f _ xs = foldr1 f xs -- Example: format a list of strings, using a comma as a seperator: mkSepStr :: [String] -> String mkSepStr xs = foldrs (\x s -> x ++ ", " ++ s) "" xs t0 = mkSepStr [] -- ==> "" t1 = mkSepStr ["hello"]-- ==> "hello" t2 = mkSepStr ["10","20","30"] -- ==> "10, 20, 30" What do the rest of you do to solve this particular problem? If there isn't a standard solution, perhaps something like foldrs would be a useful addition to the Prelude. Thanks, -antony -- Antony Courtney Grad. Student, Dept. of Computer Science, Yale University [EMAIL PROTECTED] http://www.apocalypse.org/pub/u/antony ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Representing cyclic data structures efficiently in Haskell
Hi Sarah, Representing cyclic structures is indeed somewhat tricky in a pure functional language. The obvious representation (representing the link structure implicitly in an algebraic data type) doesn't work, because you can't obvserve cycles. I recommend checking out two pieces of work in this area: 1. Martin Erwig's work on inductive representations of graphs: Inductive Graphs and Functional Graph Algorithms, Martin Erwig Journal of Functional Programming Vol. 11, No. 5, 467-492, 2001 available from: http://cs.oregonstate.edu/~erwig/papers/abstracts.html#JFP01 2. Koen Claessen and David Sands' work on observable sharing: Observable Sharing for Functional Circuit Description, Koen Claessen, David Sands, published at ASIAN '99, in Phuket, Thailand available from: http://www.math.chalmers.se/~koen/Papers/obs-shar.ps Hope that helps, -Antony -- Antony Courtney Grad. Student, Dept. of Computer Science, Yale University [EMAIL PROTECTED] http://www.apocalypse.org/pub/u/antony ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Ex 9.9 in Paul Hudak's book
Ludovic Kuty wrote: > The exercise is short. > > First, he defines a "fix" function: > fix f = f (fix f) > Which has the type (a -> a) -> a > > Then the function "remainder": > remainder :: Integer -> Integer -> Integer > remainder a b = if a < b then a else remainder (a - b) b > > The function fix, has far as i understand the matter, has no base case. > So if someone wants to evaluate it, it will indefinitely apply the function f > to itself, leading the hugs interpreter to its end. As a hint (but not a solution), attached are my own notes from when I was puzzling through fixed points myself a few years ago. This is a literate Haskell script that you can load into hugs and run. Note that my 'y' is the same as your 'fix'. I use y to derive a factorial function (fact) in terms of y that does terminate. ("Malkovich" is an obscure reference to the scene in the film "Being John Malkovich" where Malkovich goes through his own portal... :-)) -antony -- Antony Courtney Grad. Student, Dept. of Computer Science, Yale University [EMAIL PROTECTED] http://www.apocalypse.org/pub/u/antony A definition of the Y combinator in Haskell. Valery calls this the "stupid" definition of the Y combinator since it uses Haskell's recursion. Of course, if it's the "stupid" definition, and it's not immediately obvious to me why it works, wellthere's only one conclusion. Thankfully, however, I have other redeeming qualities. :-) Here was Valery's original formulation: y = \f -> let x = f x in x But, of course, Paul pointed out that this definition of y can be simplified to: > > y f = f (y f) Now let's define a generator to test out y: > factGen = \f -> \n -> if n==0 then 1 else n * f (n-1) > fact = y factGen Sure enough, if we run this under Hugs, it works: Main> fact 3 6 Main> Wow. mind-blowing. Unfortunately, I don't have "stepper" for Haskell, so I better walk through this myself to figure out what's going on. First, some types: y :: (a -> a) -> a factGen :: (Integer -> Integer) -> Integer -> Integer (Note, though, that since -> associates to the right, this is the same as: (Integer -> Integer) -> (Integer -> Integer) fact :: Integer -> Integer which all makes sense. Now let's trace through an evaluation like: fact 3 ==> (y factGen) 3 ==> ((\f -> let x = f x in x) factGen) 3 ==> (let x = factGen x in x) 3 (OK, I think this is the crucial step: ==> (let x = factGen x in (factGen x)) 3 ==> (let x = factGen x in ((\f -> \n -> if n==0 then 1 else n * f (n-1)) x)) 3 ==> (let x = factGen x in (\n -> if n==0 then 1 else n * x (n-1))) 3 ==> let x = factGen x in (if 3==0 then 1 else 3 * x (3-1)) ==> let x = factGen x in (3 * x (3-1)) ==> let x = factGen x in (3 * x 2) ==> let x = factGen x in (3 * (factGen x) 2) ==> let x = factGen x in (3 * (factGen x) 2) The above was with the original definition of y. Of course, this should be easier to follow with Paul's definition: fact 3 ==> (y factGen) 3 ==> (factGen (y factGen)) 3 ==> ((\f -> \n -> if n==0 then 1 else n * f (n-1)) (y factGen)) 3 ==> if 3==0 then 1 else 3 * ((y factGen) 2) ==> 3 * ((y factGen) 2) which obviously works. Ok, so what's going is this: x is bound to (factGen x). (factGen x) unfolds to: ((\f -> \n -> if n==0 then 1 else n * f (n-1)) x) which reduces to: \n -> if n==0 then 1 else n * x (n-1) but the "x" in the above will itself just unfold to (factGen x), yielding yet another recursive call! Note, too, that x has "type" Integer->Integer, although it is really a name for a *computation* that produces such a function when evaluated. mind-blowing. Another way to think of it: If f is Malkovich, then: x <--> (Malkovich x) <--> (Malkovich (Malkovich x)) <--> (Malkovich (Malkovich (Malkovich x))) <--> (Malkovich (Malkovich (Malkovich (Malkovich ... (Malkovich x) i.e. x unfolds to as many applications of "Malkovich" as we need to eventually reach Malkovich's fixed point. Of course, I used <--> just to indicate equivalence, not an actual reduction sequence. In normal order evaluation, we only unfold x when it's value is needed. But we'll keep doing that until we hit a fixed point (or diverge).