Re: [Haskell-cafe] Poll plea: State of GUI graphics libraries in Haskell
Sven Panne wrote: 2013/9/27 Conal Elliott co...@conal.net: [...] Am I mistaken about the current status? I.e., is there a solution for Haskell GUI graphics programming that satisfies the properties I'm looking for (cross-platform, easily buildable, GHCi-friendly, and OpenGL-compatible)? [...] Time warp! ;-) Point your browser at the g...@haskell.org archives a decade ago... I think the consensus at that time was a bit disappointing: Either one could have something portable but hard to install and alien-looking, or something non-portable but easy to install and native-looking. The fundamental UI concepts on the various platforms differed so much that there was no hope for a grand unified pretty UI library, so those GUI efforts basically ended. I think the reasoning behind this hasn't changed recently, but I would love being proven wrong. Well, the advent of modern browsers has changed the first alternative to portable, easy to install and alien-looking. That's the niche I'm belaboring with threepenny-gui. Personally, I think that the easy to install criterion beats all the others -- it is hard to use a GUI library that you can't install. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Poll plea: State of GUI graphics libraries in Haskell
Sven Panne wrote: 2013/9/27 Heinrich Apfelmus apfel...@quantentunnel.de: Actually, I'm reading about WebGL right now, and it appears to me that it should be very easy to support in Threepenny. [...] I am not sure if WebGL is enough: WebGL is basically OpenGL ES 2.0, which is again basically OpenGL 2.0 plus some extensions. OpenGL itself is currently at 4.4, and the situation regarding the supported shading language versions is even worse. In a nutshell: WebGL = ancient OpenGL. If it's enough for your purposes, fine, but otherwise I guess a lot of people want something more recent. Fair enough. I have never really worked with OpenGL and its variants, so I wouldn't know. That said, from a cursory look, I get the impression that OpenGL ES 2.0 was the recent standard on mobile platforms. For instance, iOS 7 just recently introduced OpenGL ES 3.0 support. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Store type-class polymorphic values generically
Christopher Done wrote: It's very easy to state this problem without enough details and mislead people into providing a solution for a different problem, so I'll try to include all the information and use-case. I need a function that can store a value in a concrete opaque type. I know the type of the value when I store it, and I know the type of the value when I extract it, insofar as I know the type inclusive of a class constraint context. But the container must store many different things at once. Given that I know the type of the thing when I store it and when I extract it, there ought to be a “safe’ way to do this, in the same way that Data.Dynamic is “safe”. [..] I have to ashamedly admit that I didn't read your problem description in its entirety, but maybe my vault package can help? http://hackage.haskell.org/package/vault In particular, the Locker stores arbitrary values like Dynamic , except that values are extracted and removed with the help of a Key . This gets rid of the Typeable constraint. Note that there is a fundamental problem with storing polymorphic types, which is related to the value restriction for reference types. One of the main points of the Typable class is actually that it enforces monomorphic types. Similarly, the vault library enforces monomorphic types by having newKey in the IO monad. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Store type-class polymorphic values generically
Christopher Done wrote: On 4 October 2013 10:56, Heinrich Apfelmus apfel...@quantentunnel.de wrote: In particular, the Locker stores arbitrary values like Dynamic , except that values are extracted and removed with the help of a Key . This gets rid of the Typeable constraint. lock :: Key a - a - Locker I can't pass anything with class constraints to that. I don't know what something with a class constraint means. But I guess you want to pass a value with a *polymorphic* type? This is no problem, but requires impredicative polymorphism: a = (forall b. Show b = b - IO ()) lock :: Key (forall b. Show b = b - IO ()) - (forall b. Show b = b - IO ()) - Locker Unfortunately, GHC's support for that is a little shaky, but a solution that always works is to put it in a new data type. data Dummy = Dummy { unDummy :: forall b. Show b = b - IO () } lock :: Key Dummy - Dummy - Locker It seems to me that your problem decomposes into two problems: 1. A heterogenous store for values of different types. 2. Values with polymorphic instead of monomorphic types. Solution for problem 1 are usually restricted to monomorphic types, but you can work around it. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Any precedent or plan for guaranteed-safe Eq and Ord instances?
Tom Ellis wrote: On Wed, Oct 02, 2013 at 11:24:39AM +0200, Heinrich Apfelmus wrote: I'm not sure whether the Eq instance you mention is actually incorrect. I had always understood that Eq denotes an equivalence relation, not necessarily equality on the constructor level. There's a difference between implementors being able to distingush equals, and application programmers. Internal implementations are allowed to break all sorts of invariants, but, by definition, APIs shouldn't. Are there examples where application programmers would like there so be some f, a and b such that a == b but f a /= f b (efficiency concerns aside)? I can't think of any obvious ones. I think the trouble here is that the instance data Foo = Bar | Baz instance Eq Foo where _ == _ = True is perfectly fine if the possibility to distinguish between Foo and Bar is not exported, i.e. if this is precisely an implementation detail. The LVish library sits between chairs. If you consider all Eq instances Safe in the sense of SafeHaskell, then LVish must be marked Unsafe -- it can return different results in a non-deterministic fashion. However, if only Eq instance that adhere to the exported functions preserve equivalence law are allowed, then LVish can be marked Safe or Trustworthy, but that assurance is precisely one we lack. I think the generic form of the problem is this: module LVish where -- | 'foo' expects the invariant that the -- first argument must be 'True'. foo :: Bool - String foo False = unsafeLaunchMissiles foo True = safe module B where goo = foo False What status should SafeHaskell assign to the modules LVish and B, respectively? It looks like the right assignment is: LVish - Unsafe B - Trustworthy If LVish cannot guarantee referential transparency without assumptions on external input, then it stands on a similar footing as unsafePerformIO . Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Any precedent or plan for guaranteed-safe Eq and Ord instances?
Ryan Newton wrote: Here are some examples: - data Foo = Bar | Baz instance Eq Foo where _ == _ = True instance Ord Foo where compare Bar Bar = EQ compare Bar Baz = LT compare _ _ = error I'm partial! - These would allow LVish's runPar to non-determinstically return Bar or Baz (thinking they're the same based on Eq). Or it would allow runPar to nondeterministically crash based on different schedulings hitting the compare error or not [1]. [..] [1] If you're curious why this happens, its because the Ord instance is used by, say, Data.Set and Data.Map for the keys. If you're inserting elements in an arbitrary order, the final contents ARE deterministic, but the comparisons that are done along the way ARE NOT. I'm not sure whether the Eq instance you mention is actually incorrect. I had always understood that Eq denotes an equivalence relation, not necessarily equality on the constructor level. One prominent example would be equality of Data.Map itself: two maps are equal if they contain the same key-value pairs, map1 == map2 = toAscList map1 == toAscList map2 but that doesn't mean that their internal representation -- the balanced tree -- is the same. Virtually all exported operations in Data.Map preserve this equivalence, but the library is, in principle, still able to distinguish equal maps. In other words, equality of abstract data types is different from equality of algebraic data types (constructors). I don't think you'll ever be able to avoid this proof obligation that the public API of an abstract data type preserves equivalence, so that LVish will yield results that are deterministic up to equivalence. However, you are mainly focused on equality of keys for a Map. In this case, it might be possible to move towards pointer equality and use things like Hashable or StableName . Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Fwd: [GSoC 2013] Porting Charts to Diagrams - Final Report
Jan Bracker wrote: Hello everybody, I am sorry to send this a second time. Someone hinted out that I would not reach everybody on the mailing list through the Google Groups address. I should have looked a bit more thoroughly. The Google Summer of Code 2013 is over! My project to port the charts [0] library to use diagrams [1] as an alternative to cairo [2] was a full success. [..] [0]: https://github.com/timbod7/haskell-chart/wiki [1]: http://projects.haskell.org/diagrams/ Congratulations! I think the library looks great and I will consider using it for my next plot. Is it possible to change fonts? I have found that fonts (and shadows) have a huge impact on the wow-factor of a plot. In fact, I could not help but ask a speaker during a talk what font he used for a particular plot... it just looked great! Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Poll plea: State of GUI graphics libraries in Haskell
Conal Elliott wrote: I'm polling to see whether there are will and expertise to reboot graphics and GUIs work in Haskell. I miss working on functional graphics and GUIs in Haskell, as I've been blocked for several years (eight?) due to the absence of low-level foundation libraries having the following properties: * cross-platform, * easily buildable, * GHCi-friendly, and * OpenGL-compatible. The last several times I tried Gtk2hs, I was unable to compile it on my Mac. Years ago when I was able to compile, the GUIs looked and interacted like a Linux app, which made them awkward and upleasant to use. wxHaskell (whose API and visual appearance I prefered) has for years been incompatible with GHCi, in that the second time I open a top-level window, the host process (GHCi) dies abruptly. Since my GUI graphics programs are often one-liners, and I tend to experiment a lot, using a full compilation greatly thwarts my flow. For many years, I've thought that the situation would eventually improve, since I'm far from the only person who wants GUIs or graphics from Haskell. About three years ago, I built a modern replacement of my old Pan and Vertigo systems (optimized high-level functional graphics in 2D and 3D), generating screamingly fast GPU rendering code. I'd love to share it with the community, but I'm unable to use it even myself. Two questions: * Am I mistaken about the current status? I.e., is there a solution for Haskell GUI graphics programming that satisfies the properties I'm looking for (cross-platform, easily buildable, GHCi-friendly, and OpenGL-compatible)? * Are there people willing and able to fix this situation? My own contributions would be to test and to share high-level composable and efficient GUI and graphics libraries on top of a working foundation. Hello Conal, I have been similarly dissatisfied with the state of GUI libraries in Haskell and have finally started working on one myself: [threepenny-gui][1]. Threepenny-gui uses the web browser as a display, which means that it's cross-platform, easy to install and works from GHCi! On the flip side, it doesn't support native OpenGL. [1]: http://www.haskell.org/haskellwiki/Threepenny-gui Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Poll plea: State of GUI graphics libraries in Haskell
Tikhon Jelvis wrote: Could threepenny work with webGL, or is that too far out of the scope of the project? I guess the overhead of having a server--even locally--and using a web browser might just be too much for many use cases. Actually, I'm reading about WebGL right now, and it appears to me that it should be very easy to support in Threepenny. While the communication between browser and server is comparatively slow, most of the hard work is done in the shading language anyway. The browser retrieves shading code from a `script` tag. It's straightforward to create such a tag in Threepenny, populate it, and make a few JavaScript FFI calls to start the rendering process. I currently have no plans to add WebGL support myself, but all the ingredients are in place. (Maybe wait until threepenny-0.4 , as I'm currently simplifying the FFI a bit.) PS: Conal, if you want to see whether the Threepenny + WebGL route is viable for you, it's probably a good idea to do a quick test in plain HTML + JS first, to see whether performance is good enough for your purpose. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Mistakes in documentation for weak pointers?
Dear café, I'm currently studying weak pointers in order to implement garbage collection for a small JavaScript FFI used by the threepenny-gui library [1]. While the paper [2] is fairly clear, it seems that the documentation in System.Mem.Weak [3] differs in certain aspects. Could someone help me and clarify this? I have two questions: 1. The sentence in the documentation References from the finalizer to the key are treated in the same way as references from the value to the key: they do not keep the key alive. seems incorrect in the subordinate clause. Namely, the paper only states that the weak pointer object does not keep the key alive. However, I understood that it is perfectly acceptable for the value to keep the key alive, and that this relation is not changed by mkWeak . Is this still correct? (The memo table example in the paper never stores the value itself, only a weak pointer to it, so it doesn't matter whether the value is reachable from the key or not.) 2. The sentence in the documentation A heap object is reachable if: ... It is a weak pointer object whose key is reachable. seems to differ from the paper, which states that while weak pointers are always retained if their keys are alive, they can very much be unreachable. But if I think about it, the formulation in the documentation seems to be equivalent to the paper (as far as the semantics are concerned, it does not matter whether unreachable weak pointers are tombstoned or not.). Is that correct? [1]: http://www.haskell.org/haskellwiki/Threepenny-gui [2]: http://community.haskell.org/~simonmar/papers/weak.pdf [3]: http://hackage.haskell.org/packages/archive/base/latest/doc/html/System-Mem-Weak.html Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FLTK GUI Binding in progress. Call for participation.
aditya siram wrote: Thanks for your input. However from an API coverage standpoint I think I further along than that project. Also it hasn't been updated since 2008. That said it seems to have a nice interface. Should I emulate that? One of my main goals for starting this thread (besides getting help) was to start a discussion about what the higher level abstraction should look like. There's so many choices. WxHaskell has a particularly well-designed API, see also http://legacy.cs.uu.nl/daan/download/papers/wxhaskell.pdf However, I think that event handling can be done even more elegantly and, in particular, integrated with functional reactive programming (FRP). See my recent project http://www.haskell.org/haskellwiki/Threepenny-gui for a post-wxHaskell take on a GUI API. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Proposal: Hackage's packages should be seperated by buildable
He-chien Tsai wrote: I'm sick for checking whether package is obsolete or not. I think packages build failed long time ago should be collected and moved to another page until someone fix them, or hackage pages should have a filter for checking obsolete packages. People are working on it. http://new-hackage.haskell.org/ Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Haskell] [ANN] Initial release of the threepenny-gui library, version 0.1.0.0
Henning Thielemann wrote: On Sun, 21 Jul 2013, Sergey Mironov wrote: Hi, I have a Path problem when installing threepenny-gui from Hackage. Probably somtething trivial. I have written a small script cabal-upload that tries to compile a package before uploading it to Hackage. That helps to assert that all required files are registered in the cabal file. http://hackage.haskell.org/package/cabal-scripts Nice! However, I can't find the cabal-test executable after installing your package? Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Music / MIDI help
Mark Lentczner wrote: I'm a little lost in the bewildering array of music packages for Haskell, and need some help. I'm looking to recreate one of my algorithmic music compositions from the 1980s. I can easily code the logic in Haskell. I'm looking for a the right set of packages and SW so that I can: a) generate short sequences and play them immediately, preferrably in ghci, -- but 'runHaskell Foo.hs | barPlayer' would be acceptable 2) generate MIDI files I'm on OS X. So far what I've found is: Haskore, the midi package, and the jack package - and then I'd need some MIDI software synth for the Mac, and Jack based patcher Or perhaps I want SuperCollider, and the Haskell bindings - but that seems rather low level for my needs here (I don't really need to patch together my instruments, and I don't want to have re-write the whole timing framework from scratch.) So - What's a quick easy path here? I'm also on MacOS X and had the same problem. For immediate sound output, I liked Rohan Drape's [SuperCollider bindings][hsc3], though I started to write my [own library][tomato-rubato] that abstracts away from the internals and presents a simpler interface. Maybe you can find something interesting here. It's currently dormant because the feedback loop in GHCi is still too long for my taste, though. I found Henning Thielemann's [midi][] package very useful for reading MIDI files, I guess it's equally useful for writing MIDI files. [hsc3]: http://hackage.haskell.org/package/hsc3 [midi]: http://hackage.haskell.org/package/midi [tomato-rubato]: https://github.com/HeinrichApfelmus/tomato-rubato Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] HTML framework for web-ui
Vlatko Basic wrote: Hi Heinrich, Looks simple and interesting. I browsed the git, but not much docs yet. Just examples, or have I looked at wrong places? Thanks! Only examples and Haddock documentation so far, though the latter is extensive. I see that API is still under heavy design. When do you expect the API might stabilize? The current API probably won't change much until the first release, but I can't guarantee anything beyond that. It involves lots of aesthetic decisions. (BTW, examples in Readme do not work.) That would be one of the corners where it's not ready for public consumption yet. ;) Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] HTML framework for web-ui
Vlatko Basic wrote: I'd like to start using web pages as the UI for apps. I found out for yesod, snapp and happstack as the candidates. Would you recommend any of them as better for app ui (not classical web pages)? Or maybe another one? Not sure if that's what you are looking for, but with help from Daniel Austin, I'm currently working on a small GUI library that use the web browser to display GUI elements. https://github.com/HeinrichApfelmus/threepenny-gui It's derived from Chris Done's former Ji project. It's not quite ready for public consumption yet, but any feedback is appreciated, of course. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GSoC proposal: Data Visualization
Ernesto Rodriguez wrote: For me it would already be a huge advantage if I could edit and re-evaluate expressions interactively (in a comfortable GUI, not ghci). Also a plot widget with sliders would also help. I was wondering if you know any reason the project has not been worked on for various months (as I see in the repo). Is there anyone working in this project and has a later version? I mean these are features that are even available in free math packages such as Sage. I was actually the initial mentor for this project. I'm not particularly happy about the result. As you can see, it hasn't been picked up by anyone else, including me, and I think that's because it missed the modularity goals I had in mind. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GSoC proposal: Data Visualization
Ernesto Rodriguez wrote: Dear Haskell Community, During the last months I used Haskell for machine learning, particularly in the field of Echo State Neural Networks. The main drawback I encountered is that its difficult to visualize and plot data in Haskell in spite the fact there are a couple of plotting libraries. Data visualization is very important in the field of machine learning research (not so much in machine learning implementation) since humans are very efficient to analyze graphical input to figure out what is going on in order to determine possible adjustments. I was wondering if other members of the community have experienced this drawback and would be interested in improved data visualization for Haskell, especially if there is interest to use Haskell for machine learning research. I collected my ideas in the following page: https://github.com/netogallo/Visualizer . Please provide me with feedback because if the proposal is interesting for the community I would start working with it, even if it doesn't make it to this GSoC, but a project like this will need a lot of collaboration for it to be successful. Your project is very ambitious! In fact, too ambitious. Essentially, you want to build an interactive environment for evaluating Haskell expressions. The use case you have in mind is data visualization for machine learning, but that is just a special case. If you can zoom in and out of plots of infinite time series, you can zoom in and out of audio data, and then why not add an interactive synthesizer widget to create that audio data in the first place. Your idea decomposes into many parts, each of which would easily fill an entire GSoC project on their own. * GUI. Actually, we currently don't have a GUI library that is easy to install for everyone. Choosing wxHaskell or gtk2hs immediately separates your user base into three disjoint parts. I think it's possible to use the web browser as GUI instead (https://github.com/HeinrichApfelmus/threepenny-gui). * Displaying Haskell values in a UI. You mentioned that you want matrices to come with a contextual menu where you can select different transformations on them. It's just a minor step to allow any Haskell function operating on them. I have a couple of ideas on how to do this is in a generic fashion. Unfortunately, the project from last year http://hackage.haskell.org/trac/summer-of-code/ticket/1609 did not succeed satisfactorily. There were some other efforts, but I haven't seen anything released. * UI programming is hard. You could easily spend an entire project on implementing a single visualization, for instance an infinite time series with responsive zoom. It's not difficult to implement something, but adding the right level of polish so that people want to use it takes effort. There's a reason that Matlab costs money, and there's a reason that your mentor relies on it. * Functionality specific to machine learning. Converting Vector to a format suitable for representation of matrices, etc. This is your primary interest. Note that, unfortunately, the parts depend on each other from top to bottom. It's possible to write functionality specific to machine learning, but it would be of little impact if it doesn't come with a good UI. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Announcement - HGamer3D - 0.2.1 - why netwire
Peter Althainz wrote: Hi Heinrich: Its simply the types are more cumbersome, now. In netwire you basically have one type, which is Wire with some type parameters (underlying monad, inhibition type, in-type, out-type), When underlying monad and inhibition type is choosen, you can define a type synonym and all boils done to GameWire a b in all types, events (GameWire a a), behaviours (GameWire a b), what you want. Signal inhibition makes Events and Behviours looks equal. Also the overall network has this type. And by the way, no generalized datatypes (forall t. ), which I'm also not too comfortable with. In reactive banana we have considerably more types then in netwire: - One tpye for Behaviours - One type for Events - sinks in addition: sinkoutput[text:==showNumber$result]- what is that? (I know it has something to do with feedback loops) - scary type for the network description: forallt.Frameworkst=Momentt() Thanks Peter! The distinction between Behavior and Event is something fundamental that I don't want to give up easily. They behave differently under products and coproducts, they correspond to modalities in temporal logic and they are also very useful for recursion. Concerning the sink combinator, it's actually part of the GUI bindings and not of the core library. It's used to bind, say the text value of an edit widget to display the value of a Behavior String . Likewise, the forall t. Frameworks t = Moment t () type signature is used when binding to a GUI framework. The explicit forall is only used to be get the right name for the type t , usually you would just write Frameworks t = Moment t () . Overall, I like to think that the complexity is only superficial. I agree that the type parameter t is somewhat annoying, but it's necessary for fundamental reasons. Fortunately, it has a nice conceptual interpretation as starting time. In the case of HGamer3D, the sink combinator would replace the need to declare a final wire which runs all the wires at each step. It feels a bit weird to me to have wires like guiSetPropW that perform side effects, i.e. where it makes a different whether you observe their results or not. That's a complexity where I feel that something has been swept under the rug. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Announcement - HGamer3D - 0.2.1 - why netwire
Ertugrul Söylemez wrote: Heinrich Apfelmus apfel...@quantentunnel.de wrote: You said that reactive-banana didn't feel as simple after the introduction of dynamic event switching, though. Could you pinpoint some particular thing that made you feel like that? Maybe a type signature or a tutorial or something else? I took great care trying to make the dynamic event switching stuff entirely optional, so you can use reactive-banana without understanding it at all, but I'm not sure if I succeeded. I think this is less of an issue with reactive-banana than with classic FRP in general. The type signatures of Netwire can be scary at first sight, but they are consistent throughout the entire library. Once you understand one of these type signatures you understand all of them. Once you know how to use one wire, you know how to use all others. Let me pinpoint something in particular: events. In reactive-banana events are special, in Netwire they are not. This makes dynamic switching special in reactive-banana and natural in Netwire. Let me show you an example: You want to dispaly one for ten seconds, then two for twelve seconds, then start over: myWire = one . for 10 -- two . for 12 -- myWire Events and particularly dynamic event switching is one of the main problems Netwire solves elegantly. You can add this to reactive-banana, too, but it would require changing almost the entire event interface. I concur that chaining wires with the andThen combinator is very slick, I like it a lot. Wolfgang Jeltsch recently described a similar pattern for classical FRP, namely a behavior that doesn't live forever, but actually ends at some point in time, which can be interpreted as an event occurrence. (It ends with a bang!) However, do note that the andThen combinator in netwire can only be so slick because switching restarts time (as the documentation puts it). I don't see a nice way to switch between wires that have accumulated state. How would you express the TwoCounters example [1] using dynamic event switching in netwire? (The example can be implemented without dynamic event switching, but that's not what I mean.) What about the BarTab example [2]? [1]: http://www.haskell.org/haskellwiki/Reactive-banana/Examples#twoCounters [2]: http://www.haskell.org/haskellwiki/Reactive-banana/Examples#bartab Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Announcement - HGamer3D - 0.2.1 - why netwire
Ertugrul Söylemez wrote: Heinrich Apfelmus apfel...@quantentunnel.de wrote: I concur that chaining wires with the andThen combinator is very slick, I like it a lot. Wolfgang Jeltsch recently described a similar pattern for classical FRP, namely a behavior that doesn't live forever, but actually ends at some point in time, which can be interpreted as an event occurrence. (It ends with a bang!) Well, that would work, but I wonder why then you wouldn't want to go all the way to signal inhibition. You don't need AFRP to have it. It's actually quite a light-weight change. Allow behaviors not to produce a value, i.e. somewhere in your library replace a by Maybe a. I think that the andThen combinator is slick, but I'm not sure whether I find the underlying model -- signal inhibition -- to be equally pleasing. In the context of GUI programming, chaining several events with the andThen combinator is almost never needed, so I've postponed these questions for now. How would you express the TwoCounters example [1] using dynamic event switching in netwire? (The example can be implemented without dynamic event switching, but that's not what I mean.) What about the BarTab example [2]? I've been asked that via private mail. Let me just quote my answer: This is a misconception caused by the very different nature of Netwire. In Netwire everything is dynamic. What really happens in w1 -- w2 is that at the beginning only w1 exists. When it inhibits it is removed from the network and w2 takes its place. The missing ingredient is that w2 is not actually produced by a wire, but this is equally easy and natural. Just consider the context wires: context id w This wire will dynamically create a version of 'w' for every different input, so it acts like a router that will create wires if they don't already exist. Deletion works similarly: contextLatest id 1000 w This is a version that only keeps the 1000 latest contexts. So context has the same purpose as Conal's trim combinator [1]. However, I believe that it is too inconvenient for managing very dynamic collections that need to keep track of state, as the context function significantly limits the scope of the stateful wire. That's why I've opted for a more flexible approach in Reactive.Banana.Switch , even if that introduces significant complexity in the type signatures. Again, I would be interested in an implementation of the BarTab example [2] to compare the two approaches. [1]: http://conal.net/blog/posts/trimming-inputs-in-functional-reactive-programming [2]: http://www.haskell.org/haskellwiki/Reactive-banana/Examples#bartab Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Announcement - HGamer3D - 0.2.1 - why netwire
Peter Althainz wrote: Heinrich Apfelmus wrote: Of course, I have to ask: what influenced your choice of FRP library in favor of netwire instead of reactive-banana ? good question, actually I need to thank you for your excellent tutorials on FRP and GUI on the WEB. I tried the version of reactive-banana without switches as the first FRP framework to have contact with and I liked its simplicity and the cool introduction around Excel cells you gave on the Web. My pleasure. :) I have to thank Peter Minten for writing the tutorial with Excel cells, though. HGamer3D is my personal way to get more insight into FP and Haskell especially and from the beginning I wanted to have a FRP API to try it with game examples. So your intro on FRP and the examples were very helpful with that. After reading a lot on the web it became clear, that currently reactive-banana and netwire are good candidates to start with. So why in the end I decided to use netwire for the binding? It's some personal things and I do not claim to have done a proper evaluation or comparison. I also cannot judge on performance or other relevant topics. Having said that, I can give you some points why I choosed netwire: - The cool simplicity of reactive-banana API seems to have suffered a little bit after the introduction of the switch functionality. - After getting around Monads and Applicative by great help of Learning a Haskell for great good I was shocked to see, there is even more to learn, when I detected Arrows. So I started to look at it and discovered some nice tutorials for Arrows. - What struck me was introduction of netwire author Ertugrul Söylemez on Arrows and the explanations of local state, which can be kept into an arrow. Since I was also curious on OOP and FP and game state handling, actually this raised some interest. So I think this Arrows keep local state argument was the killer feature. But also behaviours keep local state and maybe I got misguided here. - I then did some trials with netwire and I felt it's a quite comprehensive and nice API, so I got started with that. I'm mainly asking because it helps me learn about issues with reactive-banana that could be fixed. Looking at other FRP libraries for fun and learning is definitely something that should be encouraged and not something that should be fixed, so that's cool. :) You said that reactive-banana didn't feel as simple after the introduction of dynamic event switching, though. Could you pinpoint some particular thing that made you feel like that? Maybe a type signature or a tutorial or something else? I took great care trying to make the dynamic event switching stuff entirely optional, so you can use reactive-banana without understanding it at all, but I'm not sure if I succeeded. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Announcement - HGamer3D - 0.2.1 - featuring FRP based GUI and more
Peter Althainz wrote: Dear All, I'm happy to announce release 0.2.1 of HGamer3D, the game engine with Haskell API, featuring FRP based API and FRP based GUI. The new FRP API is based on the netwire package. Currently only available on Windows: http://www.hgamer3d.org. Nice work! Of course, I have to ask: what influenced your choice of FRP library in favor of netwire instead of reactive-banana ? Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Haskell] ANNOUNCE: MFlow 0.2
Alberto G. Corona wrote: The template look is very simple but it uses a lot of dynamic code behind I changed the template to something more light. http://haskell-web.blogspot.com.es/ Much better, thanks! Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: MFlow 0.2
Alberto G. Corona wrote: Hello. haskellers and, specially, web developpers. This is the second version of MFlow, a deep-first effort in the development of a platform for web applications at the higher level, by including as much haskell magic as possible. It is at the same time experimental and intended to be used in industry. I believe that haskell will not have its chance in the Web if it does not bring unique advantages and challenging paradigms beyond speed and type safety. Deep-first means that the effort is more in the addition higher level features rather than in being complete and bug free, with the conviction that feedback from real usage at the highest level is the best guide for development. Rather than to mimic other platforms in other languages, MFlow is as Haskell'ish as possible, and introduces new approaches like statefulness, event sourcing, back-execution, composable, active, self contained widgets and persistent STM. All of them collaborate to create a high level environment for web programming. This release adds bidings for WAI, blaze-html, stateful AJAX, active widgets, requirements, content management, multilanguage and URLs to pages inside stateful procedures. The package: [http://hackage.haskell.org/package/MFlow The entry in my blog, with the announcement and the philosophy behind http://haskell-web.blogspot.com.es/2013/01/announce-mflow-02.html For some reason, your blog posts are not displayed in my browser (Chrome). I block all cookies and I'm using adblock, though. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Object Oriented programming for Functional Programmers
Daniel Díaz Casanueva wrote: Hello, Haskell Cafe folks. My programming life (which has started about 3-4 years ago) has always been in the functional paradigm. Eventually, I had to program in Pascal and Prolog for my University (where I learned Haskell). I also did some PHP, SQL and HTML while building some web sites, languages that I taught to myself. I have never had any contact with JavaScript though. But all these languages were in my life as secondary languages, being Haskell my predominant preference. Haskell was the first programming language I learned, and subsequent languages never seemed so natural and worthwhile to me. In fact, every time I had to use another language, I created a combinator library in Haskell to write it (this was the reason that brought me to start with the HaTeX library). Of course, this practice wasn't always the best approach. But, why I am writing this to you, haskellers? Well, my curiosity is bringing me to learn a new general purpose programming language. Haskellers are frequently comparing Object-Oriented languages with Haskell itself, but I have never programmed in any OO-language! (perhaps this is an uncommon case) I thought it could be good to me (as a programmer) to learn C/C++. Many interesting courses (most of them) use these languages and I feel like limited for being a Haskell programmer. It looks like I have to learn imperative programming (with side effects all over around) in some point of my programming life. So my questions for you all are: * Is it really worthwhile for me to learn OO-programming? * If so, where should I start? There are plenty of functional programming for OO programmers but I have never seen OO programming for functional programmers. * Is it true that learning other programming languages leads to a better use of your favorite programming language? * Will I learn new programming strategies that I can use back in the Haskell world? Personally, I don't think that learning an imperative OO language will expand your mind in a way that Haskell does. I have started with Pascal and later C, but once I learned about Haskell, I switched to it immediately for virtually all my programming tasks and never looked back. The only thing that OO languages are good for are legacy systems, where no Haskell compiler is readily available. If you have a concrete project in mind, like an Android or iPhone app, or a client-heavy web application, it is certainly worthwhile to learn the relevant language (Java, Objective-C, JavaScript) in order to make your ideas a reality. But other than that, you already know Pascal and programming in these languages is not very different. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in haskell FRP
Nathan Hüsken wrote: On 12/08/2012 10:32 AM, Heinrich Apfelmus wrote: Fair enough, but I don't see how this can be fitted into a general pattern. If the animation state is coupled tightly to the game logic state, then the question whether the animation is part of the game logic or not does not have a clear answer anymore. Hm. I see it like this: The logic state may not depend on the rendering state. If for example the animation of an asteroid changes how or when objects collide with it, than the animation is part of the logic. If however the physics of the game treat the asteroid as a object whose shape does not change depending in the animation, than the animation is part of the rendering state. So the coupling may only be logic-rendering. Maybe discussing a concrete example could be very helpful. Could you give a minimal example that still contains the key difficulties? I put a pseudo C++ example below the mail. I use the terms model and view for the game logic and rendering respectively. The example is a little different. Asteroids explode when they collide. The moment asteroids explode, they are removed from the model (the game logic) while in the view (rendering) they still exist until the explosion animation is over. (Sorry for the late reply.) I see, that's a nice example. Indeed, if you try to model this situation with dynamic collections galaxyModel :: Behavior [AsteroidModel] galaxyView :: Behavior [AsteroidView] then you have to keep track of IDs in some way, because a change in the collection of asteroid models needs to be reflected in a corresponding change in the collection of asteroid views. identifier :: AsteroidModel - ID eCollisions :: Event [ID] eCollisions = collisions $ galaxyModel @ eTick where collisions asteroids = [identifier a | a - asteroids, b - asteroids, a `collides` b] galaxyModel = accumB initialAsteroidModels $ removeFromList $ eCollisions galaxyView = accumB initialAsteroidViews $ startExplosions $ eCollisions That said, do note that any significant use of pointers in an imperative program translates to the use of identifiers in the purely functional variant. This is very much *independent* of FRP! In other words, if you find that giving certain game objects an identity is a good way to structure your code, then you need to use identifiers, regardless of whether you use FRP or not. Of course, as you note in another message, there are other ways to structure this code. For instance, the second idea would be to use a data type type Asteroid = (Maybe AsteroidModel, AsteroidView) which represents live asteroids as (Just positionEtc, view) and dead asteroids as (Nothing, explosionView) . Then again, one unsatisfactory point about this approach is that an exploding asteroid is now represented explicitly in the game logic as a Nothing value. A third approach would be to keep an explicit list of explosions. data AsteroidModel = AsteroidModel { view :: AsteroidView, pos :: Position } data AsteroidView = AsteroidView { rotation :: Angle } data Explosion = Explosion { posExp :: Position } galaxyView :: Behavior ([AsteroidView], [Explosion]) galaxyView = (,) $ (map view $ galaxyModel) $ explosions explosions = accumB [] $ startExplosions $ eCollisions You do need an event to communicate which asteroids have exploded, but an exploding asteroid will not appear in galaxyModel anymore. Instead, it will be added as an anonymous explosion to the rendering logic. (In a sense, the asteroid views with the state variables dead = false and dead = true have been split into different types.) I find the third approach to be quite satisfactory. What is your opinion? The more I think about this example, the more I think that the underlying difficulty is not FRP, but the use of pointers / identities. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] education or experience?
Christopher Howard wrote: I'm at something of a crossroads, and I'm hoping to get a bit of free career advice. I really enjoy programming with Haskell (and a few other exotic languages), and was hoping I could eventually make a living in that sort of field. Not rich and famous, necessarily, just enough to get by comfortably. I'm trying to decide, however; should I go back to school, finish my B.S. and pursue a Masters in CompSci? Or would the time (and money) be better spent aggressively pursuing volunteer work for companies, hoping to eventually get the experience and contacts that lead to a paying job? To be honest, I don't really want to go back to school, because I learn a lot faster (and more economically) on my own. However, I'm not sure which path is the fastest, and safest, approach to an actual paycheck. Concerning a university education, there are two approaches: 1. I want to learn as much as possible 2. I want to learn just enough to get a high-paying job University is great at serving the first approach, not only because you have the freedom to skip lectures that you already know, but also because professors have a lot of interesting things to teach if you let them, and because some of your classmates will be equally interested and interesting. In other words, if you want to learn everything, then university is the right environment. On the other hand, approaching university from the second point of view usually does not justify the cost for the little benefit you obtain this way. Unfortunately, it seems to me that the tuition costs in the U.S. strongly suggest the second approach. To avoid this, I recommend to either go abroad or become very good and acquire a scholarship. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in haskell FRP
Nathan Hüsken wrote: Heinrich Apfelmus wrote: In that light, the separation seems straightforward to me. Given the time-varying values that represent game objects, bSpaceShipPosition :: Behavior Position bAsteroidPositions :: Behavior [Position] bTime :: Behavior Time you can transform and combine them into a graphic, for instance like this bSpaceShipPicture :: Behavior Graphic bSpaceShipPicture = blinkenLights $ bTime * bSpaceShipPosition bAsteroidPictures = map drawAsteroid $ bAsteroidPositions bPicture = overlay $ ((:) $ bSpaceShipPicture * bAsteroidPictures) In other words, you just combine old time-varying values into new ones, much like you would combine combine graphical plots. Also note that you can add animation a posteriori; it doesn't have to be part of the values representing a space ship. Yes, but these examples are extremely simple. The animation has no internal state. What if every Asteroid also has a animation state (which I would want to add a posteriori) and can be destroyed. Than the connection between the asteroids game logic value, and rendering value needs some kind of bookkeeping to be maintained. Fair enough, but I don't see how this can be fitted into a general pattern. If the animation state is coupled tightly to the game logic state, then the question whether the animation is part of the game logic or not does not have a clear answer anymore. Hm. You mentioned that in an imperative setting, you would use something similar to the observer pattern. Judging from the wikipedia page http://en.wikipedia.org/wiki/Observer_pattern, it seems to me that this is just the Event type, though, so I don't understand how this helps with the problem at hand. Maybe discussing a concrete example could be very helpful. Could you give a minimal example that still contains the key difficulties? Maybe a collection of asteroids that float in space, can be added or removed with a button click and who are animated as rotating rocks, all starting in a certain position when they are created? How would you use the observer pattern in this case? Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Can not use ST monad with polymorphic function
David Menendez wrote: On Thu, Nov 29, 2012 at 7:50 AM, Dmitry Kulagin dmitry.kula...@gmail.comwrote: Thank you, MigMit! If I replace your type FoldSTVoid with: data FoldMVoid = FoldMVoid {runFold :: Monad m = (Int - m ()) - m ()} then everything works magically with any monad! That is exactly what I wanted, though I still do not quite understand why wrapping the type solves the problem Short answer: It's because GHC's type system is predicative. Basically, quantified types can't be given as arguments to type constructors (other than -, which is its own thing). I'm not entirely sure why, but it apparently makes the type system very complicated from a theoretical standpoint. By wrapping the quantified type in a newtype, the argument to IO becomes simple enough not to cause problems. GHC has an extension -XImpredicativeTypes that lifts this restriction, but in my experience, it doesn't work very well. A newtype data Foo = Foo { bar :: forall a . baz a } usually works best. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in haskell FRP
Nathan Hüsken wrote: Heinrich Apfelmus wrote: Personally, I would recommend is a complete change in perspective. The main idea of FRP is that it is a method to describe the evolution of values in time. What is a game? It's just a picture that evolves in time. The user can exert influence on the evolution by clicking certain buttons on a mechanical device, but in the end, all he sees is a picture that moves. [..] That perspective certainly make sense. But couldn't one also describe a game as a set of entities (spaceships) that react to the clicking of buttons? Of course, generally speaking, you can describe it any way you like, FRP is just a perspective, not a dictatorial doctrine. But you probably mean that you want to describe spaceships within the FRP perspective, though independent of how they are displayed. That's a good point, which I missed. (The guideline of working backwards from the very final result has served me very well when developing in FRP style, though, hence my insistence on it.) In the FRP perspective, I would use a slightly different language, though. Namely, I would not say that spaceships are entities that react to button clicks, but rather that they are represented by time-varying positions that depend on past button clicks. The change is subtle but important: you invert the direction of control. Instead of having a button click do something to the spaceship (push), you have a spaceship whose present position depends on past button clicks (pull). The FRP perspective is also more holistic: you can think of a spaceship and other time-varying values as if you knew their values for all points in time, as if you were given graphical plots. (I have drawn a few pretty pictures in the slides linked to here http://apfelmus.nfshost.com/blog/2012/07/15-frp-tutorial-slides.html) If I take for example the breakout game from here [1]. It outputs an object scene of type Picture. But this picture is calculated from the objects ballPos and paddlePos. So first a game state (ballPos, paddlePos) is created and than transformed to something renderable. I believe all examples I have seen for games with FRP follow this pattern, and I would I want to do is seperate the steps of calculating the game state and calculating the renderable from it. In that light, the separation seems straightforward to me. Given the time-varying values that represent game objects, bSpaceShipPosition :: Behavior Position bAsteroidPositions :: Behavior [Position] bTime :: Behavior Time you can transform and combine them into a graphic, for instance like this bSpaceShipPicture :: Behavior Graphic bSpaceShipPicture = blinkenLights $ bTime * bSpaceShipPosition bAsteroidPictures = map drawAsteroid $ bAsteroidPositions bPicture = overlay $ ((:) $ bSpaceShipPicture * bAsteroidPictures) In other words, you just combine old time-varying values into new ones, much like you would combine combine graphical plots. Also note that you can add animation a posteriori; it doesn't have to be part of the values representing a space ship. Of course, one important question is whether to represent asteroid positions as a time-varying collection Behavior [Position] or as a collection of time-varying values [Behavior Position] . The latter form tends to require dynamic event switching, while the former form tends towards a monolithic GameState value, which would forgo many of the advantages of FRP. I don't have enough practical experience to give a useful recommendation here, but at the moment, I tend towards breaking it up as much as possible, but trying to avoid dynamic event switching. My rule of thumb is to model similar objects (asteroids) as a time-varying collection, while modeling distinct objects (player space ship) as individual behaviors. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in haskell FRP
Nathan Hüsken wrote: Hey, When writing games in other (imperative) languages, I like to separate the game logic from the rendering. For this I use something similar to the observer pattern. With rendering I mean anything only related to how objects are drawn to the screen. Animation state for example. On my journey of exploring game programming with haskell (and FRP), I wonder what a good way of archiving something similar would be. [..] So I am wondering: Is there (or can someone think of) a different pattern by which this could be archived? Or asked different: How would you do it? Personally, I would recommend is a complete change in perspective. The main idea of FRP is that it is a method to describe the evolution of values in time. What is a game? It's just a picture that evolves in time. The user can exert influence on the evolution by clicking certain buttons on a mechanical device, but in the end, all he sees is a picture that moves. How to describe picture that moves? Your large picture is probably made from smaller pictures, for instance a small picture in the shape of something we often call a spaceship. So, you can implement a game by describing the evolution of smaller pictures, and then combine these into the description of a larger picture. Now, the smaller pictures tend to have hidden state, which means that their future evolution depends a lot on the past evolution of the other small pictures. In my experience with programming in FRP, it is very useful to describe the individual pictures in terms of tiny state machines and then connect these state machines via appropriate events and behaviors to each other. The essence here is to decouple the individual state machines from each other as much as possible and only then to use the FRP abstractions to connect and combine them into a large emergent state machine. (However, it is important to keep in mind that the fundamental abstraction is not a state machine, but a time evolution that remembers the past. This helps with embracing the new perspective and not accidentally fall back to previous ways of thinking. Whether that ends up with good code is up to you to find out, but if you decide to apply a new perspective, it's best to do it in an extremist way to gain the maximum benefit -- this benefit might certainly turn out to be zero, but you will never find out if you wet your feet only a little bit.) Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Input Handling, Callbacks, State Machines
Daniel Trstenjak wrote: Hi all, I'm currently struggling in the search for a nice abstraction for the input handling of a game (it's a simple platformer with rectangular platforms). One good example is the level editor of the game. When pressing the left mouse button the creation of a new platform is started. As long as the mouse button is hold the platform can be resized by moving the mouse. When releasing the mouse button the platform is created with the current shape. The GUI library I'm using is GLFW. There are several callbacks for key, mouse button and mouse move events. Firstly I would like to be able to describe application states, like the creation of a platform or the definition of the movement of a platform. The state might add something to the current level rendering and it changes temporary the callbacks. So in the case of a platform creation, the mouse move callback would just resize the platform, the mouse button callback awaits the button release and the key callback might only allow the quitting of the current creation. Above the application states it would be nice to be able to describe the transition from one state to another. Perhaps FRP might be a solution for this. But I'm still shying away of it, because a game might have some hairy state changes and I still don't see, how FRP makes life in this regard that much easier. Indeed, this looks like a case for FRP to me. (Well, then again, I'm the author of the reactive-banana FRP library.) You may want to have a look at Andreas Bernstein's breakout clone https://github.com/bernstein/breakout which implements a small game using reactive-banana. As for complicated state changes, the worst thing that can happen is that your FRP code becomes as messy as the imperative equivalent, but the thing is that it cannot get any messier because you can translate it rather directly, so you don't lose anything. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] total Data.Map.! function
Henning Thielemann wrote: I wondered whether there is a brilliant typing technique that makes Data.Map.! a total function. That is, is it possible to give (!) a type, such that m!k expects a proof that the key k is actually present in the dictionary m? How can I provide the proof that k is in m? Same question for 'lab' (import Data.Graph.Inductive(lab)). That is, can there be a totalLab, with (totalLab gr = fromJust . lab gr) that expects a proof that the node Id is actually contained in a graph? I think it's possible. However, if you are able to track keys in a meaningful way, you are also able to reify the contents of the map in the type! At this point, it's no longer clear whether you really want that. Here's the reason. Consider the expression map' = insert key value map The idea is that the type of map' should now indicate that the key is in the map. Since map does not necessarily contain the key , you have to add to the type information. But at this point, why not add the *value* to the type as well? Instead of adding just the key to the type information, you can add a tuple (key,value) to the type by virtue of some mild form of parametricity. But at this point, you've put the whole map into the type. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Call for discussion: OverloadedLists extension
Michael Snoyman wrote: Heinrich Apfelmus wrote: Michael Snoyman wrote: Note that I wasn't necessarily advocating such a pragma. And a lot of my XML code actually *does* use two IsString instances at the same time, e.g.: Element (img :: Name) (singleton (href :: Name) (foo.png :: Text)) [NodeComment (No content inside an image :: Text)] In this particular case, would it make sense to use smart constructors instead? The idea is that you can put the polymorphism in two places: either make the output polymorphic, or make the input polymorphic. The latter would correspond to a type element :: (IsString name, IsString s, IsMap map) = name - map name s - [Element] element name map = Element (toName name) (toMap map) One benefit would be that the function will accept any list as a map, not just list literals. Just to clarify: this would be a *replacement* for OverloadedStrings usage, right? If used in conjunction with OverloadedStrings, we'd run into the too-much-polymorphism issue you describe in your initial email in this thread, since `element foo'` would become `element (fromString foo)` which would become `Element ((toName . fromString) foo)`, and `toName . fromString` makes it ambiguous what the intermediate data type is. Yes, indeed, it would be an alternative approach. Assuming this is meant are a replacement, I see two downsides. Firstly, this would work for construction, but not for deconstruction. Currently, I can do something like: handleList :: Element - Element handleList (Element ul _ _) = ... handleList e = e Good point. On the other hand, there is another extension, ViewPatterns, which solves the problem of pattern matching on abstract data types in full generality, allowing things like handleList (viewAsStrings - Element ul _ _) = ... While more intrusive, the benefit of this extension is that a lot of other code could likely become neater as well. The other is that we've only solved one specific case by providing a replacement function. In order to keep code just as terse as it is now, we'd have to provide a whole slew of replacement functions. For example, consider the code: handleList (Element ul attrs _) = case Map.lookup class attrs of If we get rid of OverloadedStrings, then we need to either provide a replacement `lookup` function which performs the conversion from String to Name, or change all lookup calls to explicitly perform that lookup. Ah, I see. Since the Name type is abstract, I feel it's alright to add the polymorphism to functions like element , but Map.lookup is indeed a problem. One option would be to make a new type NameMap specifically for Name as key, but that seems a little overkill. The other option is to bite the bullet and add the conversion by hand Map.lookup (name class) . In this case, I think I would go with a lightweight first option and simply give a new name to the Map.lookup combination and use the opportunity to sneak in some polymorphism. getAttribute name = Map.lookup (toText name) In my experience, turning all data types into abstractions works quite well, but I can see that you can't avoid an annoying conversion if you just want to use a quick Map.lookup . Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Call for discussion: OverloadedLists extension
Michael Snoyman wrote: Note that I wasn't necessarily advocating such a pragma. And a lot of my XML code actually *does* use two IsString instances at the same time, e.g.: Element (img :: Name) (singleton (href :: Name) (foo.png :: Text)) [NodeComment (No content inside an image :: Text)] In this particular case, would it make sense to use smart constructors instead? The idea is that you can put the polymorphism in two places: either make the output polymorphic, or make the input polymorphic. The latter would correspond to a type element :: (IsString name, IsString s, IsMap map) = name - map name s - [Element] element name map = Element (toName name) (toMap map) One benefit would be that the function will accept any list as a map, not just list literals. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Organizaing tests in Haskell
Simon Hengel wrote: On Sun, Sep 23, 2012 at 06:11:59PM +0200, Heinrich Apfelmus wrote: How do I access internal modules with cabal test , though? Last time I tried, I could not find a way to expose in the test section of the cabal file. It works, if you add the source directory to hs-source-dirs of the test suite (in contrast to depending on the library!), e.g.: hs-source-dirs: test, src or hs-source-dirs: test, . This still has the disadvantage, that the sources are compiled twice. But I'm not aware of a better way to do it. If you mostly use GHCi for development, it's not a big issue. I got it to work, thanks! I also had to duplicate the dependency information, but that's alright. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Call for discussion: OverloadedLists extension
Roman Cheplyaka wrote: * Heinrich Apfelmus apfel...@quantentunnel.de [2012-09-23 10:51:26+0200] Unfortunately, making literals polymorphic does not always achieve the desired effect of reducing syntax. In fact, they can instead increase syntax! In other words, I would like to point out that there is a trade-off involved: is it worth introducing a small syntactic reduction at the cost of both a small additional conceptual complexity and some syntactic enlargement elsewhere? Can't you just disable the extension when you realise that it makes your life harder? I thought so, too, but there is actually a social catch. Namely, a library/DSL can be designed with that extension in mind and advocate its use. The [scotty][] library is an example for this. In particular, the RoutePattern type is made an instance of IsString and the example code uses it extensively. If I want to disable the extension, I have to translate the example code first. When learning a library for the first time, this can be rather confusing. [scotty]: http://hackage.haskell.org/package/scotty Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Call for discussion: OverloadedLists extension
Michael Snoyman wrote: (Prettier formatting available at: https://gist.github.com/3761252) Many of us use the OverloadedStrings language extension on a regular basis. It provides the ability to keep the ease-of-use of string literal syntax, while getting the performance and correctness advantages of specialized datatypes like ByteString and Text. I think we can get the same kind of benefit by allowing another literal syntax to be overloaded, namely lists. Actually, I am already somewhat reserved about the OverloadedStrings proposal. The core point of the OverloadedSomething extensions is that they address a syntactic issue, namely that we can write example instead of (pack example) The extension does this by making the literal polymorphic. Unfortunately, making literals polymorphic does not always achieve the desired effect of reducing syntax. In fact, they can instead increase syntax! In other words, I would like to point out that there is a trade-off involved: is it worth introducing a small syntactic reduction at the cost of both a small additional conceptual complexity and some syntactic enlargement elsewhere? The increase in syntax happened to me while using one of the json libraries. The thing is that if a receiver function is agnostic in the string used, or if it is otherwise polymorphic, receive1 :: IsString s = s - Foo receive2 :: JSON s = s - Foo then I have to specify the type of the overloaded argument (either by a type annotation or a monomorphic function call). In other words, without OverloadedStrings , I was able to write receive2 example but with the extension, I now have to write receive2 (pack example) A similar effect can be seen with the good old numeric literals. Sometimes, you just have to introduce a type signature (:: Int) to make a program unambiguous. In this light, I don't think that the trade-off made by the OverloadedLists extension is big enough. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Organizaing tests in Haskell
Simon Hengel wrote: Of course others are still able to import your Internal modules That is not necessarily true. For libraries, you can list internal modules as other-modules (in contrast to exposed-modules) in you Cabal file. That way they are not part of the public interface of your library. How do I access internal modules with cabal test , though? Last time I tried, I could not find a way to expose in the test section of the cabal file. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Platform Versioning Policy: upper bounds are not our friends
Brent Yorgey wrote: Yitzchak Gale wrote: For actively maintained packages, I think the problem is that package maintainers don't find out promptly that an upper bound needs to be bumped. One way to solve that would be a simple bot that notifies the package maintainer as soon as an upper bound becomes out-of-date. This already exists: http://packdeps.haskellers.com/ Indeed. It even has RSS feeds, like this http://packdeps.haskellers.com/feed/reactive-banana Extremely useful! Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Data structure containing elements which are instances of the same type class
Antoine Latter wrote: It should be pretty easy to write an adapter function of type String - (Show a = a). The type needs to be String - (exists a. Show a = a) which is equivalent to String - (forall a. Show a = a - c) - c Here is the implementation of the adapter newtype ExistsShow = E { showE :: String } instance Show ExistsShow where show = showE withShow :: String - (forall a. Show a = a - c) - c withShow s f = f (E s) Essentially, the point is that the types are equivalent ExistsShow == exists a. Show a = a Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Key-Parametrized Lookup Table
Alexander Foremny wrote: At first glance I noticed some problems with the vault library for my particular approach. Despite from being unique, Key values don't appear to carry any information like the Label I need. However, it might be possible to work around that. The more grave problem seems to be that a Key cannot be (de-)serialized. This might be impossible due to the type parameter a in Key a. Vault is intended to be a store for values of any type, so it doesn't include any restriction on the type a in Key a . For reasons of type safety, this means that keys have to be abstract. You can't create a typed key from an untyped label alone, because this would allow you to coerce a value to a different type (just create two keys of different types from the same label). However, it is no problem to fix the types of values to some finite collection. That should work. You have to reify the type a in Key a in the value of the key. I think it's possible to use a data type family for the map type. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Unambiguous choice implementation
Bartosz Milewski wrote: I see. So your current implementation is not push, is it? Reactive-banana includes two implementations: a pull-based model implementation that specifies the semantics and a push-based implementation for actual work. So, yes, reactive-banana is push-based. Note that the qualification push-based is not straightforward to obtain. For instance, Elm is implementation in a style that looks push-based, but it doesn't optimize the case where no event / change happens, so it has the same efficiency as a pull-based implementation. Conal's unamb combinator may have a similar problem, but I'm not sure. The original pull implementation in Fran also used Maybe events, but that was considered inefficient. How is Reactive Banana better then Fran then? I don't know much about the implementation of Fran , but if I remember correctly, it uses the representation Behavior a = Time - a and this introduces other efficiency problems not present in reactive-banana. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Unambiguous choice implementation
Bartosz Milewski wrote: Thanks, Heinrich. I looked at the examples and at the references you provided. I understand the semantic model, so I guess I'm mostly trying to understand the implementation. Ok. As I mentioned, if you just want to use the library there is no need to understand the implementation. Conal's paper was mostly about refining data structures in order to provide better implementation. It's all beautiful up to the point where he introduces the unamb hack. How did you manage to work around this problem and implement event merging efficiently? Essentially, Conal implements events as type Event a = [(Time,a)] The trouble is that when merging events, this representation forces you to wait for both events. In other words, the pattern match union ((t1,x1):e1) ((t2,x2):e2) = ... needs to know the times of occurrences of both events before it can return the earlier one. The trouble is that the merge function should have returned the earlier one right away, before knowing exactly when the later one happens. The purpose of the unamb hack is circumvent that problem. Reactive-banana's very simple solution to this problem is to represent events as type Event a = [(Time, Maybe a)] and impose the additional invariant that all events in your program are synchronized, in the sense that they indicate their occurrences at the same times^1. If they don't occur at that time, they use Nothing . Then, you can implement merge simply as union ((t1,x1):e1) ((t2,x2):e2) = -- we always have t1 = t2 (t1, combine x1 x2) : union e1 e2 where combine (Just x) Nothing = Just x -- only left occurs combine Nothing (Just y) = Just y -- only right occurs combine (Just x) (Just y) = Just x -- simultaneous occurrence combine Nothing Nothing = Nothing -- neither occurs Since the times are given globally, we can also remove them and obtain type Event a = [Maybe a] This is how Reactive.Banana.Model does it. Of course, keeping track of a lot of Nothing is something that can be optimized. The optimization to apply here is to transform the implementation into a push-driven style. I haven't published the details yet, but some design notes can be found here. http://apfelmus.nfshost.com/blog/2011/04/24-frp-push-driven-sharing.html ^1: Note that the times do not need to follow a uniform time step. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Unambiguous choice implementation
Bartosz Milewski wrote: I'm trying to understand Reactive Banana, but there isn't much documentation to go about. I haven't written any beginner documentation yet because the API is still in flux. The homepage http://www.haskell.org/haskellwiki/Reactive-banana and Stackoverflow http://stackoverflow.com/questions/tagged/frp are great resources, though. Feel free to drop me a line if you have questions as well. How is RB positioned vis a vis Elliott (and then there is the earlier Elliot and Hudak, and the later Elliot with the push implementation and type classes). The semantics from Elliott (double 't', by the way) and reactive-banana are essentially the same, but I have taken the liberty to modernize many function names. You can pretty much directly translate Conal's examples to reactive-banana, except for those involving the switcher combinator. The approaches to implementation are very different, though. Functional reactive programming is one of the cases where you have to learn the API without understanding its implementation. (But have a look at the Reactive.Banana.Model module, which provides a simplified model implementation.) Do you have a toy applet that demonstrates the use of Reactive Banana, something like Elliotts Bezier editor, http://research.microsoft.com/pubs/69665/deop-tr.pdf ? Reactive-banana comes with a lot of examples, mentioned here: http://www.haskell.org/haskellwiki/Reactive-banana#documentation By the way, Conal's Bezier editor doesn't make much use of the switcher combinator, so you can directly translate it into reactive-banana. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Unambiguous choice implementation
Bartosz Milewski wrote: I'm reading Conal Elliot's paper, Push-Pull FRP. At some point he needs an unambiguous choice operator, essentially to implement select: a future that waits for one of its future arguments to fire. His implementation of unamb creates two threads racing on a shared MVar. By his own admission, this is very inefficient. My question is, is there a better implementation? The thing about unambiguous choice is that it goes beyond the dynamic semantics of the Haskell language. To implement it, you either need a new evaluation model built into the compiler, or you have to fake it somehow and that is likely to be inefficient. Also note that Conal's paper describes just one possible implementation of FRP. My reactive-banana library uses an implementation that doesn't require unambiguous choice at all. For a basic model, see http://hackage.haskell.org/packages/archive/reactive-banana/latest/doc/html/Reactive-Banana-Model.html The key idea is to keep all events synchronous and to reify some cases of this event does not occur right now. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] The use of continuation monad in C++
Bartosz Milewski wrote: I published a blog for C++ programmers about the advantages of using the continuation monad in dealing with asynchronous API, concurrency, and parallelism. I explained the concepts in Haskell and the translated them into C++. http://fpcomplete.com/asynchronous-api-in-c-and-the-continuation-monad/ I always found the continuation monad to be hard to understand. An easier yet equivalent approach is presented in my Operational Monad Tutorial [1]. [1]: http://themonadreader.wordpress.com/2010/01/26/issue-15/ [2]: http://www.haskell.org/haskellwiki/Operational Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Mac and Gtk2hs problem
Tanja Piechnick wrote: All right. After a re-installation I could load my GTK2HS example successfully. But I received another error. What is the meaning of that? A wrong architecture? Prelude :l guitest.hs [1 of 1] Compiling Main ( guitest.hs, interpreted ) Ok, modules loaded: Main. *Main main Loading package transformers-0.2.2.0 ... linking ... done. Loading package mtl-2.0.1.0 ... linking ... done. Loading package array-0.3.0.2 ... linking ... done. Loading package containers-0.4.0.0 ... linking ... done. Loading package bytestring-0.9.1.10 ... linking ... done. Loading package cairo-0.12.3.1 ... linking ... done. Loading package glib-0.12.3.1 ... can't load .so/.DLL for: intl (dlopen(/usr/local/Cellar/gettext/0.18.1.1/lib/libintl.dylib, 9): no suitable image found. Did find: /usr/local/Cellar/gettext/0.18.1.1/lib/libintl.dylib: mach-o, but wrong architecture) *Main That's a 64bit / 32bit problem. The gtk library you installed via homebrew is probably 64bit while the GHC you use (7.0.4) seems to be 32bit. Either you reinstall GTK with 32bit support, or you use the 64bit version of the recently released Haskell Platform. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] heterogeneous environment
Ben wrote: while working on an STM-like library, i ran into the issue of trying to create a transaction log for reads / writes of heterogeneous reference types. i don't have a good answer to this problem. the problem is twofold : first, the general heterogeneous collection problem, and second, connecting a reference to its log. I've had similar problems while implementing my reactive-banana library. The solution is described here http://apfelmus.nfshost.com/blog/2011/09/04-vault.html and also available as a cabal package http://hackage.haskell.org/package/vault Note that the Vault data type is probably not quite what you are looking for as it represents a whole collection of references. But have a look at the type Data.Vault.Locker in the vault-0.2 package which I have just uploaded to hackage. Oleg's email describes essentially the same solution. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] why are applicative functors (often) faster than monads? (WAS Google Summer of Code - Lock-free data structures)
Ben wrote: however, this does bring up a general question : why are applicative functors (often) faster than monads? malcolm wallace mentioned this is true for polyparse, and heinrich mentioned this is true more generally. is there a yoga by which one can write monadic functors which have a specialized, faster applicative implementation? I'm not knowledgeable enough on the multicore stuff, but I can comment on the monad vs applicative issue. Applicative functors are not per se faster than monads, it's just that the former can encode static analysis while the latter can't. As you can see from the type of bind (=) :: m a - (a - m b) - m b the structure of the computation in the second argument, i.e. its various side effects, can depend on a value of type a , which is only available at run-time. In contrast, the type of apply (*) :: m (a - b) - m a - m b makes it clear that the side effects are the same, no matter what the value of a will be at run-time. In other words, the structure of the computation is known statically. For parsers, interesting analyses are * Does a parser accept the empty set? * What are the first characters that a parser can accept? The answers can be obtained easily enough from an applicative functors, for instance acceptsEmpty (pure x) = True acceptsEmpty (f * g) = acceptsEmpty f acceptsEmpty g But the corresponding analysis for monadic parsers is either harder or hopelessly inefficient because we don't know the structure of the parser until we run it on some input. See also this answer on StackOverflow: http://stackoverflow.com/a/7863380/403805 Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Google Summer of Code - Lock-free data structures
Ben wrote: perhaps it is too late to suggest things for GSOC -- but stephen tetley on a different thread pointed at aaron turon's work, which there's a very interesting new concurrency framework he calls reagents which seems to give the best of all worlds : it is declarative and compositional like STM, but gives performance akin to hand-coded lock-free data structures. he seems to have straddled the duality of isolation vs message-passing nicely, and can subsume things like actors and the join calculus. http://www.ccs.neu.edu/home/turon/reagents.pdf he has a BSD licensed library in scala at https://github.com/aturon/ChemistrySet if someone doesn't want to pick this up for GSOC i might have a hand at implementing it myself. That looks great! While I didn't take the time to understand the concurrency model in detail, the overall idea is to use arrows that can be run atomically runAtomically :: Reagent a b - (a - IO b) This is very similar to STM: combining computations within the monad/arrow is atomic while combining computations outside the monad/arrow can interleave them. runAtomically (f . g) -- atomic runAtomically f . runAtomically g -- interleaving Actually, it turns out that the Reagent arrow is also a monad, but the author seems to claim that the static arrow style enables certain optimizations. I haven't checked his model in detail to see whether this is really the case and how exactly it differs from STM, but we know that situations like this happen for parser combinators. Maybe it's enough to recast reagents as an applicative functor? To summarize: the way I understand it is that it's apparently possible to improve the STM monad by turning it into an arrow. (I refer to STM in a very liberal sense here: whether memory is transactional or not is unimportant, the only thing that matters is a computation that composes atomically.) Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is this a correct explanation of FRP?
Peter Minten wrote: The updated document, which now lives at http://www.haskell.org/haskellwiki/FRP_explanation_using_reactive-banana contains a Making the example runnable section which shows how connect the example with the outside world. I have added a link from the reactive-banana project homepage. Thanks for your great explanation! Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is this a correct explanation of FRP?
Peter Minten wrote: I've been trying to get my head around Functional Reactive Programming by writing a basic explanation of it, following the logic that explaining something is the best way to understand it. Am I on the right track with this explanation? I think so. Your explanation looks fine to me, except for one really subtle but really important issue: Stepped sounds a lot like stepper and we can create that function by making a few small adjustments. type Time = Int stepper :: a - [(Time, a)] - (Time - a) stepper d es = \t - case takeWhile (\(t', _) - t' = t) es of [] - d xs - snd (last xs) The correct definition of stepper usesinstead of = ... case takeWhile (\(t', _) - t' t) es of ... In other words, at the moment t == t' , the behavior still returns the old value, not the new value from the event. This important because it allows for recursive definitions, like let b = accumB 1 e e = (+) $ b @ eKey If you were to use = here, then the new value of the behavior would depend on itself and the result would be undefined. (Actually, even if you use the correct definition for stepper, trying to implement Event and Behavior in terms of [(Time,a)] and Time - a in Haskell would give undefined on this recursive example. That's because the data types still aren't lazy enough, you have to use another model. That's one reason why implementing FRP has traditionally been hard.) P.S. Sorry about the long mail, the explanation ended up a little longer than I originally expected. :) I know it was time to get a blog when my mailing list posts got too long. ;) Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is this a correct explanation of FRP?
Michael Snoyman wrote: First you state that we shouldn't use `union` for the `ePitch` Event, and then you used it for `bOctave`. Would it be more efficient to implement bOctave as someting like: eOctave :: Event t (Int - Int) eOctave = filterJust toStep $ eKey where toStep '+' = Just (+ 1) toStep '-' = Just (subtract 1) toStep _ = Nothing bOctave :: Behavior t Octave bOctave = accumB 0 eOctave It's largely a matter of efficiency in notation rather than efficiency in run-time. Also, I'm left wondering: how would you create a new event stream in the first place? You're telling us to just rely on `eKey`, which is fair, but a great follow-up would demonstrate building it. Looking through the docs I found `newEvent`, but I'm not quite certain how I would combine it all together. It's best to look at the example for that and peruse the documentation in Reactive.Banana.Frameworks in case something is unclear. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Google Summer of Code - Lock-free data structures
Florian Hartwig wrote: Hi everyone, I would like to do the GSoC project outlined in http://hackage.haskell.org/trac/summer-of-code/ticket/1608 One of Haskell's great strengths is its support for all kinds of concurrent and parallel programmming, so I think that the Haskell ecosystem would benefit from having a wider range of efficient concurrent data structures. Also, more selfishly, I remember reading the article in CACM last summer and thinking that the whole idea of updating data structures directly using atomic compare-and-swap was really cool, so I would love to have an excuse to play around with it. Some (initial) ideas for lock-free data structures worth implementing: 1. A lock-free priority queue, e.g. using the approach based on skip-lists explained in [2] 2. Stacks, see [1] and [3] 3. Hash tables [4] but if anyone has other suggestions, I would obviously happy to hear them. Since I don't know much about concurrency, I have a simple question: what is the difference between atomic compare-and-swap and software transactional memory? Both are lock-free? Is it possible to implement every data structure based on CAS in terms of STM? What are the drawbacks? The other way round? Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] a code that cannot compile with or without NoMonomorphismRestriction
Ketil Malde wrote: Ting Lei tin...@hotmail.com writes: (f1, f2) = let commond_definitions = undefined in let f1 = id.show f2 x = ( x) in (f1, f2) I think the type signatures should be: f1 :: Show a = a - String and f2 :: Ord b = b - b - Bool When I define these separately, this works: f1 :: Show a = a - String f1 = id . show f2 :: Ord b = b - b - Bool f2 = flip () But when I define them as a pair f1 :: Show a = a - String f2 :: Ord b = b - b - Bool (f1,f2) = (id . show, flip ()) I get an error message: Line 9: 1 error(s), 0 warning(s) Couldn't match expected type `forall a. Show a = a - String' with actual type `a - String' When checking that `f1' has the specified type `forall a1. Show a1 = a1 - String' Defining the pair at once works: p :: (Show a, Ord b) = (a - String, b - b - Bool) p = (id . show, flip ()) I guess that didn't help a lot, somebody with deeper GHC-fu than me will have to step in. The problem is that f1 and f2 are polymorphic functions. To put polymorphic functions in a pair, you need *impredicative polymorphism*. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Google Summer of Code - Lock-free data structures
Florian Hartwig wrote: Heinrich Apfelmus wrote: So while the two are related, CAS is a machine primitive that works for a single operation and on a single word while STM is a software abstraction that isolates sequences of operations on multiple memory locations from each other. Is it possible to implement every data structure based on CAS in terms of STM? What are the drawbacks? The other way round? I think so. Atomically reading and writing a single memory location (which CAS does) is just a very simple transaction. But using a CAS instruction should be more efficient, since STM has to maintain a transaction log and commit transactions, which creates some overhead. Ah, I see. In that case, it may be worthwhile to implement the CAS instruction in terms of STM as well and measure the performance difference this makes for the final data structure. After all, STM is a lot more compositional than CAS, so I'd like to know whether the loss of expressiveness is worth the gain in performance. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Mathematics and Statistics libraries
Tom Doris wrote: If you're interested in UI work, ideally we'd have something similar to RStudio as an environment, a simple set of windows encapsulating an editor, a repl, a plotting panel and help/history, this sounds superficial but it really has an impact when you're exploring a data set and trying stuff out. Concerning UI, the following project suggestion aims to give GHCi a web GUI http://hackage.haskell.org/trac/summer-of-code/ticket/1609 But one of your criteria is that a good UI should come with a help system, too, right? Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Open-source projects for beginning Haskell students?
John Lato wrote: From: Heinrich Apfelmus Also, as far as I am aware, you can't do low-level audio programming in SuperCollider, i.e. play a list of samples that you've calculated yourself. That's cool if you're only interested in sound design, but bad for learning how audio programming works. I think this charge is a bit unfair. If you really want to do low-level stuff, it's possible within SC. You just have to work in SuperCollider, not Haskell (AFAIK). Ah, right, I meant from within Haskell, i.e. by communicating with the SC3 server component. Even in SC you have to write unit generators in C, I think, but I may well be mistaken. However, it is possible to transfer audio data between Haskell and Csound, in several ways. The hCsound package comes with some examples of transferring the audio input and output streams between csound and haskell. Named channels provide for even more complicated routing if you like. I didn't know about the hCsound package, that might have saved me some work. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Open-source projects for beginning Haskell students?
erik flister wrote: giving a real-time audio synthesizer in the style of functional reactive programming. you know about yampasynth right? Yes. In fact, their glue code was extremely helpful for understanding OpenAL. As for the FRP, I prefer a style without arrows, though, see my reactive-banana library. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Open-source projects for beginning Haskell students?
Tom Murphy wrote: If you want to do Haskell audio synthesis, you could also use hsc3 (good start here: http://slavepianos.org/rd/ut/hsc3-texts/). With hsc3 you can start on serious audio synthesis with only a few lines of Haskell. In my opinion it could use a much larger community. While Rohan's bindings to SuperCollider are great, I have found that SuperCollider itself is quite difficult to understand for a new user. (My tomata-rubato project aims to be much easier to learn.) Also, as far as I am aware, you can't do low-level audio programming in SuperCollider, i.e. play a list of samples that you've calculated yourself. That's cool if you're only interested in sound design, but bad for learning how audio programming works. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Open-source projects for beginning Haskell students?
serialhex wrote: On Sat, Mar 17, 2012 at 11:01 AM, Heinrich Apfelmus apfel...@quantentunnel.de wrote: The task is to implement a small audio synthesizer in Haskell. seriously?!?! i'm not in his class, but i'm game! i learn better when i'm working on something interesting, and i want to make my (currently pretty pathetic) haskell better and i *LOOOE* audio! a haskell-based synth (or series of synths) would be really spiffy! what do i have to know / learn / do? Well, it's up to you, really. You need to learn a bit how audio synthesis works, for instance starting with the following links. http://www.acoustics.salford.ac.uk/acoustics_info/sound_synthesis/ http://en.wikibooks.org/wiki/Sound_Synthesis_Theory http://en.wikipedia.org/wiki/Category:Sound_synthesis_types Then, it's best to learn by programming various wave forms yourself and playing around with them. I just finished implementing the necessary Haskell backend for playing raw audio data. You can find it here: http://hackage.haskell.org/package/tomato-rubato-openal The testSine function demonstrates how it works. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] We *have* been accepted into the Google Summer of Code
Sajith T S wrote: Heinrich Apfelmus apfel...@quantentunnel.de wrote: Just for reference, here the direct link that is now online: http://www.google-melange.com/gsoc/org/google/gsoc2012/haskell How up-to-date/relevant are the projects in the ideas page? http://hackage.haskell.org/trac/summer-of-code/report/1 (For example, I believe build multiple Cabal packages in parallel is a successful project from last year's summer of code.) The newly created project suggestions are definitely up-to-date, but the older ones may be outdated. To know for sure, you can ask about specific projects on the mailing list, which is a good idea anyway. I'm sorry that the list is not in top shape, but that's probably because there is no curator. Also, why is Mentor: not-accepted for many (all?) of them? The Mentor field has no significance, simply ignore it. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] We *have* been accepted into the Google Summer of Code
Edward Kmett wrote: Just to clarify, since I've been getting a ton of emails on the topic, we *have* been accepted to the Google Summer of Code this year. The list on their site is still updating, and we should appear there shortly. Just for reference, here the direct link that is now online: http://www.google-melange.com/gsoc/org/google/gsoc2012/haskell Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Open-source projects for beginning Haskell students?
Brent Yorgey wrote: I am currently teaching a half-credit introductory Haskell class for undergraduates. This is the second time I've taught it. The last time, for their final project I gave them the option of contributing to an open-source project; a couple groups took me up on it and I think it ended up being a modest success. So I'd like to do it again this time around, and am looking for particular projects I can suggest to them. Do you have an open-source project with a few well-specified tasks that a relative beginner (see below) could reasonably make a contribution towards in the space of about four weeks? I'm aware that most tasks don't fit that profile, but even complex projects usually have a few simple-ish tasks that haven't yet been done just because no one has gotten around to it yet. Finding a suitable project seems tricky to me as most real-world projects usually involve at least one nasty corner like interfacing with a C library, which is usually too hard for someone who just became comfortable with the traditional list origami. With that caveat, I do have a small task that may be suitable and that is useful to me in the context of my reactive-banana library and my yet undisclosed tomato-rubato project. The task is to implement a small audio synthesizer in Haskell. Of course, implementing high-performance audio synthesis is too challenging a task for a Haskell beginner, but there is one particular approach that I would like to see performance measurements of. More specifically, the idea is the following: 1a. Implement a handful of combinators for generating audio as a lazy list of samples type Audio = [Sample] 1b. Get it out of the speakers. (I can find a library for that.) This will be slooow. 2. Implement the same handful of combinators for a different representation, namely a lazy list of memory blocks with 64 samples each type Block = Data.Vector.Vector -- 64 samples type Audio = [Block] In other words, each block is filled in an aggressively optimized inner loop while the blocks are shuffled around with ordinary Haskell functions. 3. Do performance measurements on 2 and test whether it can be run in real-time. So, the task does involve an external library and some knowledge about GHC's optimization, but hopefully nothing too fancy. How is this task useful for me? If the performance is good enough, I can replace the lazy lists with Event / Behavior from reactive-banana , giving a real-time audio synthesizer in the style of functional reactive programming. If it doesn't work out, then the students had a fun project to work on, which is just as well. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Prettier pretty-printing of data types?
Christopher Done wrote: Maybe an Emacs script to expand the nodes nicely: http://www.youtube.com/watch?v=6ofEZQ7XoEA I don't find mere pretty printing that useful compared to the “expanding” paradigm I'm used to in Chrome and Firebug. Great demo video. My recent GSoC project suggestions aims to make that available to non-Emacsers, via the web browser. http://hackage.haskell.org/trac/summer-of-code/ticket/1609 Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Summer of Code idea: Haskell Web Toolkit
Jurriën Stutterheim wrote: Currently, however, it is still a bit of a pain to compile larger UHC JS projects, since Cabal support for UHC's different backends is limited. This could be one potential goal for your GSoC project: make it possible to type `cabal configure cabal build` and find a complete JS application in your dist folder. [..] I think this would make a nice GSoC project. The scope of the above should be about right, but if you would be done way ahead of time, there are plenty of relevant related things you could work on (e.g., a UHC JS-specific Haskell Platform-like package). If this sounds interesting to you, let me know and I can send you some more detailed information about the UHC JS backend.. As for mentoring, I might be able to help out there, but since the above project would revolve more around Cabal and not so much around the UHC internals, there might be more suitable mentors out there. This sounds like a great GSoC project to me. Maybe you can add it to the list of project suggestions, Jurriën? http://hackage.haskell.org/trac/summer-of-code/report/1 Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] If you'd design a Haskell-like language, what would you do different?
Jerzy Karczmarczuk wrote: Well... Personally I hate thinking about bottom as value. I don't do this. I NEVER teach that. And, I am a lazy guy, almost all my Haskell programs are strongly based on laziness. I'll tell you what I teach, and you might throw some tomatoes... The fundamental thing that differentiates Haskell from other languages and the source of it power - if I might cite you - is that we don't see the difference between an object and the process which creates it. (The difference demands that we speak about the call-by-need, etc...) The bottom, as sin (2*pi), or Text may be seen as processes. Anyway, a lazy list IS a process /par excellence/. The _|_ entity is a process which refuses to give you a value (or does it in a deadly way). Your program manipulates processes. A process in some computational context must do something - or not. The bottom never does anything useful. While it's ultimately an issue of nomenclature, applying the terminus value to _|_ is a good idea, because it allows us to answer questions like the following: Question: What is (the denotation of, the value of) x = and $ take 5 $ cycle [True,False] where cycle xs = fix (xs++) Answer: x = False If you treat _|_ as a value, this answer can be obtained by straightforward algebraic manipulation. If you treat _|_ as an operational construct, you will have to perform graph reduction to see the answer, but then you have to worry about the *order* in which you perform your reduction steps. It's not wrong to perform graph reduction, and any student should do it at one point in their lives, but the restriction to operational semantics would miss an important abstraction that is part of the Haskell spirit. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Summer of Code idea: Haskell Web Toolkit
Chris Smith wrote: My first impression on this is that it seems a little vague, but possibly promising. My impression is also that this project proposal is rather vague. The general goal Haskell as client-side language for websites is clear and worthwhile, but I can't tell from the proposal whether the project will succeed or not, or, more importantly, *what* it will succeed at. The way I see it is that a successful GSoC proposal has to embody four key points: 1. One specific goal - I want to compile Haskell to JS via UHC's backend 2. in a larger context - as a step towards Haskell as a client-side language for websites. 3. that is accompanied by a successful example - To demonstrate that this works, I will write a small Asteroids game with HTML5 and Haskell 4. and that others can build upon - Moreover, I want to make it really easy for others to use the Haskell-JS compilation from cabal. The last point is extremely important: you don't want to build a hobbled prototype that languishes in a dark corner of github, you want to build a great software that changes the world by solving an important problem and making this solution really easy to use! Alejandro, your proposal mentions several different specific goals, each of which can be the basis for a successful GSoC project: * Make UHC's Haskell-JS compilation easy to use. * Design combinators for DOM manipulation in functional style, f.i. zippers. Note that this goal does *not* involve running Haskell on the client-side, the focus is solely on the design of combinators. This means that you'd have to use another example, for instance XML parsing. Of course, the idea is that this can be reused when someone else manages to run Haskell on the client. * Design combinators for remote procedure calling via HTTP/AJAX. Again, there is no Haskell running in the browser, the showcase would be two Haskell processes that communicate with each other via HTTP/AJAX. Each of these goals is a tangible improvement on the status quo and specific enough to be completed in a single GSoC project. Of course, the one specific goal is not supposed to be a limit, it is meant to be a foundation. If there is time remaining, the student is free to work on whatever he dreams of. By all means, don't hesitate to reach for the sky, but help us climb to the tree top first. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell showcase in 5 minutes
Arnaud Bailly wrote: Hello Cafe, I will be (re)presenting Haskell in a Batlle Language event Wednesday evening: A fun and interactive contest where various programming language champions try to attract as much followers as possible in 5 minutes. Having successfully experimented the power of live coding in a recent Haskell introduction for the Paris Scala User Group, I would like to do the same but given the time frame I need a simpler example than the music synthesizer program. So I would like to tap in the collective wisdom looking for some concise, eye-opening, mind-shaking and if possible fun example of what one can achieve in Haskell. Things that sprung to my mind are rather dull: prime factors, fibonacci numbers. A morse code decoder, perhaps? http://apfelmus.nfshost.com/articles/fun-with-morse-code.html Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Best FRP package for newbie
edgar klerks wrote: As beginner I really liked reactive-banana. I used it in a inhouse project for the graphical user interface (wx) and I found it easier to use than the imperative approach. Unfortunately the reactive-banana-wx package seems to be broken on 7.2. Actually, it's a weird bug in GHC 7.2 that break reactive-banana-wx. Watching the build log on Hackage is fun: sometimes it doesn't build, then it does build, then not. Fortunately, everything works fine on GHC 7.0.4 . Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Best FRP package for newbie
Arnaud Bailly wrote: Hello, I am interested in exploring more in depth FRP. I had a look at the wiki page and started to explore reactive which looked promising at first glance and backed by quite a few articles and tutorials, but 1) it did not install properly on my haskell platform and 2) from the mailing-list archives it seems to have died a couple of years ago. So my question is : What package would you recommend me to get my hands dirty with FRP? I am mostly interested in things related to music and network programming, if that matters. Of course, I recommend my reactive-banana library. http://haskell.org/haskellwiki/Reactive-banana http://www.haskell.org/haskellwiki/Reactive-banana/Examples Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Google Summer of Code 2012 Announced
Andrei Varanovich wrote: One question to more experienced GSoC'ers. I do understand that this is important to find mentors in advance. As soon as I think nowadays it is critical for the programming language ecosystem to handle BigData [1], have a proposal to implement HDFS [1] support for CloudHaskell [2] with some MapReduce abstractions. What would be the right way to communicate with potential mentors? I looked at http://hackage.haskell.org/trac/summer-of-code/ and it seems there is not so much going on there. Or, perhaps, this mailing list is just OK? I think that Johan Tibell's advice applies to students as well: if you have a project idea, then 1. Write a proposal that will make people cheer and swoon. In particular, it should be useful to a lot of people from the Haskell community and you should demonstrate why you're capable of completing it, for instance by finding a very good scope for the project or maybe because your first name rhymes with Simon. 2. Advertise it on the mailing list and/or reddit and/or Google+, so that people can read it and give feedback. Incorporating said feedback is a good idea. 3. If the proposal piques everyone's interest, I'm sure that someone will volunteer to be a mentor. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Google Summer of Code 2012 Announced
Sergiu Ivanov wrote: Heinrich Apfelmus wrote: What's the time frame for project proposals? I have two ideas in my head that I think are unusually cool. To make a successful SOC project, they need a bit of preparation on my part, though, so I'm wondering how much time I have to implement a proof of concept or two. This is the official timeline: http://www.google-melange.com/document/show/gsoc_program/google/gsoc2012/faqs#timeline Looking forward to reading your übercool proposals :-) Ok, I gather that project proposals should be ready around 17 March 2012. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Google Summer of Code 2012 Announced
Johan Tibell wrote: Hi all, Here's a heads-up that this year's Google of Code is kicking off. My experience from the last few years is that we can maximize the output we get from GSoC by being proactive and writing down semi-detailed explanations of what kind of projects we'd like to see, instead of letting the students pick themselves. Here we go, I've written up a proposal: http://apfelmus.nfshost.com/blog/2012/02/14-summer-of-code-proposal.html Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Google Summer of Code 2012 Announced
Johan Tibell wrote: Here's a heads-up that this year's Google of Code is kicking off. My experience from the last few years is that we can maximize the output we get from GSoC by being proactive and writing down semi-detailed explanations of what kind of projects we'd like to see, instead of letting the students pick themselves*. What's the time frame for project proposals? I have two ideas in my head that I think are unusually cool. To make a successful SOC project, they need a bit of preparation on my part, though, so I'm wondering how much time I have to implement a proof of concept or two. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Fancy REPL
serialhex wrote: Heinrich Apfelmus wrote: I'm not so sure about the soon part, but yes, using FRP to make music is part of the plan. you know, i've been thinking about this recently, and while i need more haskell skillz if i want to do some sound synthesis, i think it would be really spiffy to work on something like that! are you working on this privately or do you have a public repo one can clone? a fully-haskell sound synth program would be really spiffy!! (esp if one could code new synths in real-time in haskell) Folks have been doing sound synthesis in Haskell for a long time; in particular, I'm currently building on Rohan Drape's bindings to SuperCollider http://slavepianos.org/rd/ut/hsc3-texts/hsc3-tutorial.html There's also Henning Thielemann who managed to do real-time audio editing in Haskell by performing run-time compilation with LLVM http://hackage.haskell.org/package/synthesizer Still, I think there's a need (I certainly have it) for a simple-to-use package that makes it really easy to play with sound synthesis in Haskell, i.e. that supports instant gratification. I'm currently working on a project called 'tomato-rubato' that aims to do precisely that. I'll put up a github repo once I have something that is glued together by duct tape rather than spit. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Fancy REPL
Dear list, the Show class is extremely useful for exploring Haskell in a terminal, but sometimes, I just want something fancier. For instance, I'm currently dabbling with sound generation and it is only natural that I want to hear the sound instead of seeing a textual representation. Another example would be graphics, that are simply drawn on screen whenever you evaluate their value. Of course, this is simple to implement with a class class Demonstrable a where demo :: a - IO () instance Demonstrable Sound where demo = play instance Demonstrable Sound where demo = draw instance Demonstrable GUI where demo = run etc. However, I don't want to reinvent the wheel, small as it may be, hence my question: is there a package on hackage that already defines a class similar to Demonstrable ? Or any other projects in this direction, like, say, a fancy REPL built on wxHaskell? Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Fancy REPL
Tom Murphy wrote: Heinrich Apfelmus wrote: For instance, I'm currently dabbling with sound generation and it is only natural that I want to hear the sound instead of seeing a textual representation. Does this mean we're going to see music FRP examples soon?! I'm not so sure about the soon part, but yes, using FRP to make music is part of the plan. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] space-efficient, composable list transformers [was: Re: Reifying case expressions]
Jan Christiansen wrote: On Jan 2, 2012, at 2:34 PM, Heinrich Apfelmus wrote: Without an explicit guarantee that the function is incremental, we can't do anything here. But we can just add another constructor to that effect if we turn ListTo into a GADT: data ListTo a b where CaseOf :: b - (a - ListTo a b) - ListTo a b Fmap :: (b - c) - ListTo a b - ListTo a c FmapCons :: b - ListTo a [b] - ListTo a [b] I did not follow your discussion but how about using an additional GADT for the argument of Fmap, that is data Fun a b where Fun :: (a - b) - Fun a b Cons :: a - Fun [a] [a] data ListTo a b where CaseOf :: b - (a - ListTo a b) - ListTo a b Fmap :: Fun b c - ListTo a b - ListTo a c and provide a function to interpret this data type as well interpretFun :: Fun a b - a - b interpretFun (Fun f) = f interpretFun (Cons x) = (x:) for the sequential composition if I am not mistaken. (.) :: ListTo b c - ListTo a [b] - ListTo a c (CaseOf _ cons) . (Fmap (Cons y) b) = cons y . b (Fmap f a) . (Fmap g b) = Fmap f $ a . (Fmap g b) a . (CaseOf nil cons)= CaseOf (interpret a nil) ((a .) . cons) a . (Fmap f b) = fmap (interpret a . interpretFun f) b -- functor instance instance Functor (ListTo a) where fmap f = normalize . Fmap (Fun f) normalize :: ListTo a b - ListTo a b normalize (Fmap (Fun f) (Fmap (Fun g) c)) = fmap (f . g) c normalize x = x Cheers, Jan Nice, that is a lot simpler indeed, and even closer to the core of the idea. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] space-efficient, composable list transformers [was: Re: Reifying case expressions]
Sebastian Fischer wrote: Your `ListTo` type achieves space efficiency for Applicative composition of list functions by executing them in lock-step. Because of the additional laziness provided by the `Fmap` constructor, compositions like interpret a . interpret b can also be executed in constant space. However, we cannot use the space efficient Applicative combinators again to form parallel compositions of sequential ones because we are already in the meaning type. We could implement composition for the `ListTo` type as follows (.) :: ListTo b c - ListTo a [b] - ListTo a c a . b = interpret a $ b But if we use a result of this function as argument of *, then the advantage of using `ListTo` is lost. While interpret ((,) $ andL * andL) runs in constant space, interpret ((,) $ (andL . idL) * (andL . idL)) does not. The ListTransformer type supports composition in lock-step via a category instance. The meaning of `ListTransformer a b` is `[a] - [b]` with the additional restriction that all functions `f` in the image of the interpretation function are incremental: xs `isPrefixOf` ys == f xs `isPrefixOf` f ys [..] The Applicative instance for `ListTransformer` is different from the Applicative instance for `ListTo` (or `ListConsumer`). While interpret ((,) $ idL * idL) is of type `[a] - ([a],[a])` transformList ((,) $ idL * idL) is of type `[a] - [(a,a)]`. [..] Ah, so ListTransformer is actually quite different from ListTo because the applicative instance yields a different type. Then again, the former can be obtained form the latter via unzip . I have a gut feeling that the laziness provided by the `Fmap` constructor is too implicit to be useful for the kind of lock-step composition provided by ListTransformer. So I don't have high hopes that we can unify `ListConsumer` and `ListTransformer` into a single type. Do you have an idea? Well, the simple solution would be to restrict the type of (.) to (.) :: ListTo b c - ListTransformer a b - ListTo a c so that the second argument is guaranteed to be incremental. Of course, this is rather unsatisfactory. Fortunately, there is a nicer solution that keeps everything in the ListTo type. The main problem with Fmap is that it can be far from incremental, because we can plug in any function we like: example :: ListTo a [a] example = Fmap reverse Without an explicit guarantee that the function is incremental, we can't do anything here. But we can just add another constructor to that effect if we turn ListTo into a GADT: data ListTo a b where CaseOf :: b - (a - ListTo a b) - ListTo a b Fmap :: (b - c) - ListTo a b - ListTo a c FmapCons :: b - ListTo a [b] - ListTo a [b] The interpretation for this case is given by the morphism interpret (FmapCons x g) = fmap (x:) $ interpret g and sequential composition reads -- sequential composition -- interpret (a . b) = interpret $ interpret a $ b (.) :: ListTo b c - ListTo a [b] - ListTo a c (CaseOf _ cons) . (FmapCons y b) = cons y . b (Fmap f a) . (FmapCons y b) = Fmap f $ a . (FmapCons y b) (FmapCons x a) . (FmapCons y b) = FmapCons x $ a . (FmapCons y b) a . (CaseOf nil cons) = CaseOf (interpret a nil) ((a .) . cons) a . (Fmap f b)= fmap (interpret a . f) b Of course, the identity has to be redefined to make use of the new guarantee idL :: ListTo a [a] idL = caseOf [] $ \x - FmapCons x idL I'm going to omit the new definition for the applicative instance, the full code can be found here: https://gist.github.com/1550676 With all these combinators in place, even examples like liftA2 (,) (andL . takeL 3) (andL . idL) should work as expected. While nice, the above solution is not perfect. One thing we can do with ListTransformer type is to perform an apply first and then do a sequential composition. a . (b * c) This only works because the result of * is already zipped. And there is an even more worrisome observation: all this work would have been superfluous if we had *partial evaluation*, i.e. if it were possible to evaluate expressions like \xs - f (4:xs) beneath the lambda. Then we could dispense with all the constructor yoga above and simply use a plain type ListTo a b = [a] - b with the applicative instance instance Applicative (ListTo a) where pure b = const b (f * x) cs = case cs of [] - f [] $ x [] (c:cs) - let f' = f . (c:); x; = x . (c:) in f' `partialseq` x' `partialseq` (f' * x') to obtain space efficient parallel and sequential composition. In fact, by using constructors, we are essentially doing partial evaluation by hand. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http
Re: [Haskell-cafe] On the purity of Haskell
Steve Horne wrote: Heinrich Apfelmus wrote: Maybe it helps to try to find an example of a function f :: A - B for some cleverly chosen types A,B that is not pure, i.e. does not return the same values for equal arguments. [..] For your specific challenge, place that as a left-hand argument in a bind... f :: Int - IO Int f = getAnIntFromTheUser = \i - return (i+1) Well, the value of i isn't decidable until runtime. The value of i+1 is not decidable until runtime. The value of return (i+1) is not decidable until runtime and so on. It can only be partially evaluated at compile-time, but when it is fully evaluated, you get a different IO action returned by f depending on what Int you got from the user. The function f :: Int - IO Int f x = getAnIntFromTheUser = \i - return (i+x) is pure according to the common definition of pure in the context of purely functional programming. That's because f 42 = f (43-1) = etc. Put differently, the function always returns the same IO action, i.e. the same value (of type IO Int) when given the same parameter. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] On the purity of Haskell
Conal Elliott wrote: I wrote that post to point out the fuzziness that fuels many discussion threads like this one. See also http://conal.net/blog/posts/notions-of-purity-in-haskell/ and the comments. I almost never find value in discussion about whether language X is functional, pure, or even referentially transparent, mainly because those terms are used so imprecisely. In the notions-of-purity post, I suggest another framing, as whether or not a language and/or collection of data types is/are denotative, to use Peter Landin's recommended replacement for functional, declarative, etc. I included some quotes and a link in that post. so people can track down what denotative means. In my understanding, Haskell-with-IO is not denotative, simply because we do not have a (precise/mathematical) model for IO. And this lack is by design, as explained in the toxic avenger remarks in a comment on that post. I often hear explanations of what IO means (world-passing etc), but I don't hear any consistent with Haskell's actual IO, which includes nondeterministic concurrency. Perhaps the difficulties could be addressed, but I doubt it, and I haven't seen claims pursued far enough to find out. Personally, the operational semantics given in SPJ's Tackling the Awkward Squad always struck me as an accurate model of how GHC performs IO. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] On the purity of Haskell
Conal Elliott wrote: Heinrich Apfelmus wrote: The function f :: Int - IO Int f x = getAnIntFromTheUser = \i - return (i+x) is pure according to the common definition of pure in the context of purely functional programming. That's because f 42 = f (43-1) = etc. Put differently, the function always returns the same IO action, i.e. the same value (of type IO Int) when given the same parameter. Two questions trouble me: How can we know whether this claim is true or not? What does the claim even mean, i.e., what does the same IO action mean, considering that we lack a denotational model of IO? I think you can put at least these troubles to rest by noting that f 42 and f (43-1) are intentionally equal, even though you're not confident on their extensional meaning. The idea is to represent IO as an abstract data type type IO' a = Program IOInstr a data Program instr a where Return :: a - Program instr a Then :: instr a - (a - Program instr b) - Program instr b instance Monad (Program instr) where return = Return (Return a) = g = g a (i `Then` f) = g = i `Then` (\x - f x = g) date IOInstr a where PutChar :: Char - IOInstr () GetChar :: IOInstr Char etc... So, two values of type IO' a are equal iff their program codes are equal (= intensional equality), and this is indeed the case for f 42 and f (43-1) . Therefore, the (extensional) interpretations of these values by GHC are equal, too, even though you don't think we know what these interpretations are. (Of course, programs with different source code may be extensionally equal, i.e. have the same effects. That's something we would need a semantics of IO for.) Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] On the purity of Haskell
Steve Horne wrote: Heinrich Apfelmus wrote: Purity has nothing to do with the question of whether you can express IO in Haskell or not. The beauty of the IO monad is that it doesn't change anything about purity. Applying the function bar :: Int - IO Int to the value 2 will always give the same result: Yes - AT COMPILE TIME by the principle of referential transparency it always returns the same action. However, the whole point of that action is that it might potentially be executed (with potentially side-effecting results) at run-time. Pure at compile-time, impure at run-time. What is only modeled at compile-time is realized at run-time, side-effects included. Well, it's a matter of terminology: impure /= has side effects. The ability of a language to describe side effects is not tied to its (im)purity. Again, purity refers to the semantics of functions (at run-time): given the same argument, will a function always return the same result? The answer to this question solely decides whether the language is pure or impure. Note that this depends on the meaning of function within that language. In C, side-effects are part of the semantics of functions, so it's an impure language. In Haskell, on the other hand, functions will always return the same result, so the language is pure. You could say that side effects have been moved from functions to some other type (namely IO) in Haskell. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] On the purity of Haskell
Gregg Reynolds wrote: Donn Cave wrote: Quoth Gregg Reynolds wrote: Look again at the sentence you trimmed off the end: Of course, the point is that this result is an *IO action* of type IO Int, it's not the Int you would get when executing this action. I believe that more or less points to the key to this discussion. If it didn't make sense to you, or didn't seem relevant to the question of pure functions, then it would be worth while to think more about it. Ok, let's parse it out. …it's not the int you would get 'when executing this action. Close, but no cooky: it's not any kind of int at all (try doing arithmetic with it). IO Int is a piece of rhetoric for the mental convenience of the user; Haskell does not and cannot know what the result of an IO action is, because it's outside the scope of the language (and computation). (The Int part of IO Int refers to the input, not the output; it's just a sort of type annotation.) It's not even a computation, unless you want to take a broad view and include oracles, interaction, etc. in your definition of computation. Why would IO Int be something special or mysterious? It's an ordinary value like everything else; it's on the same footing as [Char], Maybe Int, Int - String, Bool, and so on. I see no difference between the list [1,2,3] :: [Int] and the action pick a random number between 1 and 6 :: IO Int . Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] On the purity of Haskell
Steve Horne wrote: Heinrich Apfelmus wrote: Again, purity refers to the semantics of functions (at run-time): given the same argument, will a function always return the same result? The answer to this question solely decides whether the language is pure or impure. Note that this depends on the meaning of function within that language. In C, side-effects are part of the semantics of functions, so it's an impure language. In Haskell, on the other hand, functions will always return the same result, so the language is pure. You could say that side effects have been moved from functions to some other type (namely IO) in Haskell. Anyway, if you're using IO actions, your code is not referentially transparent and is therefore impure - by your own definition of impure. Causing side-effects may not be pedantically the issue, but the mix of causing and reacting to them - ie interacting with the outside - clearly means that some of your function results are dependent on what's happening outside your program. That includes side-effects outside your program yet caused by program program. No, that's not my definition of impure. Also, my Haskell code is referentially transparent even though I'm using IO actions. If this sounds paradoxical, then it's probably worth mulling about some more. Maybe it helps to try to find an example of a function f :: A - B for some cleverly chosen types A,B that is not pure, i.e. does not return the same values for equal arguments. Chris Smith explains it very eloquently and Donn Cove and Jerzy Karczmarczuk say the same thing. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] On the purity of Haskell
Steve Horne wrote: This is just my view on whether Haskell is pure, being offered up for criticism. I haven't seen this view explicitly articulated anywhere before, but it does seem to be implicit in a lot of explanations - in particular the description of Monads in SBCs Tackling the Awkward Squad. I'm entirely focused on the IO monad here, but aware that it's just one concrete case of an abstraction. Warning - it may look like trolling at various points. Please keep going to the end before making a judgement. To make the context explicit, there are two apparently conflicting viewpoints on Haskell... 1. The whole point of the IO monad is to support programming with side-effecting actions - ie impurity. 2. The IO monad is just a monad - a generic type (IO actions), a couple of operators (primarily return and bind) and some rules - within a pure functional language. You can't create impurity by taking a subset of a pure language. My view is that both of these are correct, each from a particular point of view. Furthermore, by essentially the same arguments, C is also both an impure language and a pure one. [...] Purity has nothing to do with the question of whether you can express IO in Haskell or not. The word purity refers to the fact that applying a value foo :: Int - Int (a function) to another value *always* evaluates to the same result. This is true in Haskell and false in C. The beauty of the IO monad is that it doesn't change anything about purity. Applying the function bar :: Int - IO Int to the value 2 will always give the same result: bar 2 = bar (1+1) = bar (5-3) Of course, the point is that this result is an *IO action* of type IO Int , it's not the Int you would get when executing this action. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell meta-programming
John Lato wrote: From: Heinrich Apfelmus apfel...@quantentunnel.de * Meta-programming / partial evaluation. When designing a DSL, it is often the case that you know how to write an optimizing compiler for your DSL because it's usually a first-order language. However, trying to squeeze that into GHC rules is hopeless. Having some way of compiling code at run-time would solve that. Examples: ** Conal Elliott's image description language Pan ** Henning Thielemann's synthesizer-llvm I've been thinking about this, and I suspect that meta-programming in Haskell may not be that far off. Suppose you have a Meta monad data Meta a = Meta { runMeta :: a} with the magical property that the compiler will optimize/recompile expressions of type `Meta a` when they are run via `runMeta`. That would provide usable metaprogramming, and I think it would have all the desired type properties etc. Of course no compiler currently has that facility, but we could use a different monad, perhaps something like this: data ThMeta a = ThMeta { runThMeta :: Language.Haskell.TH.ExpQ } now we just need to get the compiler to run an arbitrary TH splice and check that the types match after `runThMeta` is called. I think this is already possible via the GHC api. It would have the undesirable property that some expressions could be ill-typed, and this wouldn't be known until run-time, but it's a start. That's about as far as I got before I discovered a much more worked-out version on Oleg's site (with Chung-chieh Shan and Yukiyoshi Kameyama). Of course they've tackled a lot of the awkward typing issues that my simple construct rudely pushes onto the user. I'm probably showing my naivety here, and I haven't fully digested their papers yet, but I wouldn't be surprised to see applications using Haskell metaprogramming within a relatively short time. You are probably referring to the paper Kameyama, Y; Kiselyov, O; Shan, C. Computational Effects across Generated Binders: Maintaining future-stage lexical scope. http://www.cs.tsukuba.ac.jp/techreport/data/CS-TR-11-17.pdf As far as I understand, they are dealing with the problem of binding variables in your ThMeta thing. While this is certainly useful, I think the main problem is that GHC currently lacks a way to compile Template Haskell splices (or similar) at runtime. For instance, Henning is currently using LLVM to dynamically generate code, but the main drawback is that you can't freely mix it with existing Haskell code. Put differently, I would say that DSLs often contain stages which are first-order and thus amenable to aggressive optimization, but they frequently also contain higher-order parts which should at least survive the optimization passes. A simple example would be list fusion on [Int - Int]: the fusion is first-order, but the list elements are higher-order. You need some kind of genuine partial evaluation to deal with that. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Reifying case expressions [was: Re: On stream processing, and a new release of timeplot coming]
Sebastian Fischer wrote: Heinrich Apfelmus wrote: Likewise, each function from lists can be represented in terms of our new data type [...] length' :: ListTo a Int length' = CaseOf (0) (\x - fmap (1+) length') length = interpret length' This version of `length` is tail recursive while the previous version is not. In general, all functions defined in terms of `ListTo` and `interpret` are spine strict - they return a result only after consuming all input list constructors. This is what Eugene observed when defining the identity function as idC = CaseOf [] (\x - (x:) $ idC) This version does not work for infinite lists. Similarly, `head` and `take` cannot be defined as lazily as in the standard libraries. Indeed, the trouble is that my original formulation cannot return a result before it has evaluated all the case expressions. To include laziness, we need a way to return results early. Sebastian's ListTransformer type does precisely that for the special case of lists as results, but it turns out that there is also a completely generic way of returning results early. In particular, we can leverage lazy evaluation for the result type. The idea is, of course, to reify another function. This time, it's going to be fmap data ListTo a b where Fmap :: (b - c) - ListTo a b - ListTo a c CaseOf :: b - (a - ListTo a b) - ListTo a b (GADT syntax due to the existential quantification implied by Fmap ). To see why this works, have a look at the interpreter interpret :: ListTo a b - ([a] - b) interpret (Fmap f g)= fmap f (interpret g) interpret (CaseOf nil cons) = \ys - case ys of [] - nil (x:xs) - interpret (cons x) xs In the case of functions, fmap is simply function concatenation fmap f (interpret g) = f . interpret g Now, the point is that our interpretation returns part of the result early whenever the function f is lazy and returns part of the result early. For instance, we can write the identity function as idL :: ListTo a [a] idL = CaseOf [] $ \x - Fmap (x:) idL When interpreted, this function will perform a pattern match on the input list first, but then the Fmap will ensure that we return the first element of the result. This seems incredible, so I encourage the reader to check this by looking at the reduction steps for the expression interpret idL (1:⊥) To summarize, we do indeed have id = interpret idL . Of course, the result type is not restricted to lists, any other type will do. For instance, here the definition of a short-circuiting and andL :: ListTo Bool Bool andL = CaseOf True $ \b - Fmap (\c - if b then c else False) andL testAnd = interpret andL (True:False:undefined) -- *ListTo testAnd -- False With the right applicative instance, it also possible to implement take and friends, see also the example code at https://gist.github.com/1523428 Essentially, the Fmap constructor also allows us to define a properly lazy function const . To avoid confusion, I chose new names for my new types. data ListConsumer a b = Done !b | Continue !b (a - ListConsumer a b) I know that you chose these names to avoid confusion, but I would like to advertise again the idea of choosing the *same* names for the constructors as the combinators they represent data ListConsumer a b = Const b | CaseOf b (a - ListConsumer a b) interpret :: ListConsumer a b - ([a] - b) interpret (Const b) = const b interpret (CaseOf nil cons) = \ys - case ys of [] - nil (x:xs) - interpret (const x) xs This technique for designing data structures has the huge advantage that it's immediately clear how to interpret it and which laws are supposed to hold. Especially in the case of lists, I think that this approach clears up a lot of confusion about seemingly new concepts like Iteratees and so on: Iteratees are just ordinary functions [a] - b, albeit with a slightly different representation in terms of familiar combinators like case of, const, or fmap. The turn combinators into constructors technique is the staple of designing combinator libraries and goes back to at least Hughes' famous paper John Hughes. The Design of a Pretty-printing Library. (1995) http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.38.8777 Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] MIDI-controlled application
Stephen Tetley wrote: Events in FRP / Yampa are typically key presses / mouse movement, so a MIDI controller generating Note-on / Note-off events would be a direct analogue to key presses. More problematic is that FRP models hybrid (continuous and discrete) systems. For me at least, MIDI seems essentially discrete - a stream of control events. In MIDI files control events are twinned with a time stamp so they can be played. Presumably events are instantaneous in real-time interactive MIDI - not something I've looked at. Working with an FRP system like Yampa might add a lot of complexity, which admittedly you should be able to ignore - but initially it might be difficult to identify what parts are needed for a mostly discrete system like MIDI. (If you are time-stamping MIDI events yourself you will presumably need to sample a running clock which seems like a continuous behaviour...) Unfortunately I can't think of any systems in Haskell that are more discrete than continuous so you might have to choose a FRP system anyway. Concerning FRP, I would like to advertise my reactive-banana library here, which tries to follow Conal Elliott's semantics with behaviors and events. http://www.haskell.org/haskellwiki/Reactive-banana I intend to do audio / MIDI programming in the future, so it's going to be well-supported for your particular purpose, even. That said, I haven't started to use it for MIDI myself yet, so I appreciate any kind of feedback! If you want to learn reactive-banana, I recommend that you have a look at the source code of the model implementation in Reactive.Banana.Model. It's intended to be really simple to understand and it's the authoritative reference for the semantics of the actual implementation (which is far from simple to understand). As you can see, the model uses infinite lists. The advantage of the actual implementation, especially for MIDI, is that it is *real-time*, something which is tricky to do with infinite lists. Still, you could probably use the model as a guide for cooking up your own FRP library. Incidentally, I've been working on a MIDI animation language for the last couple of days based on the animation language in Paul Hudak's book. I've wanted continuous behaviours to model modulating volumes (crescendos, decrescendos) and panning, but I've found the work tough going for modelling the note lists where I want the system discrete in both input (specification) and output. Consider me interested. How does your approach compare to Conal-style FRP with behaviors and events? Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Reifying case expressions [was: Re: On stream processing, and a new release of timeplot coming]
Eugene Kirpichov wrote: In the last couple of days I completed my quest of making my graphing utility timeplot ( http://jkff.info/software/timeplotters ) not load the whole input dataset into memory and consequently be able to deal with datasets of any size, provided however that the amount of data to *draw* is not so large. On the go it also got a huge speedup - previously visualizing a cluster activity dataset with a million events took around 15 minutes and a gig of memory, now it takes 20 seconds and 6 Mb max residence. (I haven't yet uploaded to hackage as I have to give it a bit more testing) The refactoring involved a number of interesting programming patterns that I'd like to share with you and ask for feedback - perhaps something can be simplified. The source is at http://github.com/jkff/timeplot The datatype of incremental computations is at https://github.com/jkff/timeplot/blob/master/Tools/TimePlot/Incremental.hs . Strictness is extremely important here - the last memory leak I eliminated was lack of bang patterns in teeSummary. Your StreamSummary type has a really nice interpretation: it's a reification of case expressions. For instance, consider the following simple function from lists to integers length :: [a] - Int length xs = case xs of [] - 0 (y:ys) - 1 + length ys We want to reify the case expression as constructor of a data type. What type should it have? Well, a case expression maps a list xs to a result, here of type Int, via two cases: the first case gives a result and the other maps a value of type a to a function from lists to results again. This explanation was probably confusing, so I'll just go ahead and define a data type that represents functions from lists [a] to some result of type r data ListTo a r = CaseOf r (a - ListTo a r) interpret :: ListTo a r - ([a] - r) interpret (CaseOf nil cons) xs = case xs of [] - nil (y:ys) - interpret (cons y) ys As you can see, we are just mapping each CaseOf constructor back to a built-in case expression. Likewise, each function from lists can be represented in terms of our new data type: simply replace all built-in case expressions with the new constructor length' :: ListTo a Int length' = CaseOf (0) (\x - fmap (1+) length') length = interpret length' The CaseOf may look a bit weird, but it's really just a straightforward translation of the case expression you would use to define the function go instead. Ok, this length function is really inefficient because it builds a huge expression of the form (1+(1+...)). Let's implement a strict variant instead lengthL :: ListTo a Int lengthL = go 0 where go !n = CaseOf (n) (\x - go (n+1)) While we're at it, let's translate two more list functions foldL' :: (b - a - b) - b - ListTo a b foldL' f b = Case b (\a - foldL' f $! f b a) sumL:: ListTo Int Int sumL= foldL' (\b a - a+b) 0 And now we can go for the point of this message: unlike ordinary functions from lists, we can compose these in lock-step! In particular, the following applicative instance instance Applicative (ListTo a) where pure b = CaseOf b (const $ pure b) (CaseOf f fs) * (CaseOf x xs) = CaseOf (f x) (\a - fs a * xs a) allows us to write a function average :: ListTo Int Double average = divide $ sumL * lengthL where divide a b = fromIntegral a / fromIntegral b that runs in constant space! Why does this work? Well, since we can now inspect case expressions, we can choose to evaluate them in lock-step, essentially computing sum and length with just one pass over the input list. Remember that the original definition average xs = sum xs / length xs has a space leak because the input list xs is being shared. Remarks: 1. Reified case expressions are, of course, the same thing as Iteratees, modulo chunking and weird naming. 2. My point is topped by scathing irony: if Haskell had a form of *partial evaluation*, we could write applicative combinators for *ordinary* functions [a] - r and express average in constant space. In other words, partial evaluation would make it unnecessary to reify case expressions for the purpose of controlling performance / space leaks. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] If you'd design a Haskell-like language, what would you do different?
Alexander Solla wrote: And denotational semantics is not just nice. It is useful. It's the best way to understand why the program we just wrote doesn't terminate. Denotational semantics is unrealistic. It is a Platonic model of constructive computation. Alan Turing introduced the notion of an oracle to deal with what we are calling bottom. An oracle is a thing that (magically) knows what a bottom value denotes, without having to wait for an infinite number of steps. Does Haskell offer oracles? If not, we should abandon the use of distinct bottoms. The /defining/ feature of a bottom is that it doesn't have an interpretation. Huh? I don't see the problem. Introducing bottom as a value is a very practical way to assign a well-defined mathematical object to each expression that you can write down in Haskell. See http://en.wikibooks.org/wiki/Haskell/Denotational_semantics It's irrelevant whether _|_ is unrealistic, it's just a mathematical model anyway, and a very useful one at that. For instance, we can use it to reason about strictness, which gives us information about lazy evaluation and operational semantics. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] If you'd design a Haskell-like language, what would you do different?
Tillmann Rendel wrote: Hi, Robert Clausecker wrote: Image you would create your own language with a paradigm similar to Haskell or have to chance to change Haskell without the need to keep any compatibility. What stuff would you add to your language, what stuff would you remove and what problems would you solve completely different? I would try to improve the language's support for the embedding of domain-specific embedded languages (aka. combinator libraries). Such embedding requires the integration of a domain-specific language's syntax, static semantics and dynamic semantics. Some (more or less far fetched) ideas about these three areas follow. I think this is a very good point. The things I would like to see: * Better syntax for observable sharing. Doaitse Swierstra proposed a grammer construct that is basically a let statement where the binder names can be observed. I'm not entirely sure whether that is the most general or sufficient syntax, but something along these lines. * Meta-programming / partial evaluation. When designing a DSL, it is often the case that you know how to write an optimizing compiler for your DSL because it's usually a first-order language. However, trying to squeeze that into GHC rules is hopeless. Having some way of compiling code at run-time would solve that. Examples: ** Conal Elliott's image description language Pan ** Henning Thielemann's synthesizer-llvm Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell Platform
Jeremy O'Donoghue wrote: Jerzy Karczmarczuk wrote: B. Does anybody care about wxHaskell? Actually there has been quite a bit of work on wxHaskell recently, although most has not made it into the mainline yet. The archives of wxhaskell-users and wxhaskell-devel (both at Sourceforge) contain the details, but a short summary below: [..] In short, while there has not been much headline grabbing activity, we actually have a lot going on, and I hope it will be ready for wider use in the next month or two. This is mostly dependent on me getting my act together as lead maintainer. Awesome work! For those interested in wxHaskell, I would like to mention that it's now possible to program GUIs in a purely functional style, using functional reactive programming (FRP). See also http://haskell.org/haskellwiki/Reactive-banana http://haskell.org/haskellwiki/Reactive-banana/Examples Jeremy, I would love to be able to use wxHaskell from ghci on MacOS X; that would speed up my GUI development cycle considerably. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Interpreter with Cont
Tim Baumgartner wrote: Thanks a lot! Althaugh I have some understanding of the Haskell basics and the most important monads, I feel that I have to see more well designed code in order to become a good Haskeller. Can somebody make suggestions what materials are best to work through in order to achieve this? Are there easy research papers about Haskell programming? Or should I try the Monad.Reader? I'm looking for topics that either can be used directly in many situations or that show some functional principles that boost my creativity and functional thinking. You may want to start with the Functional Pearls http://www.haskell.org/haskellwiki/Research_papers/Functional_pearls In particular, I recommend * Richard Bird. A program to solve Sudoku. * Graham Hutton. The countdown problem. * Martin Erwig and Steve Kollmansberger. Probabilistic functional programming in Haskell. * Conor McBride and Ross Paterson. Applicative Programming with Effects. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] is Haskell missing a non-instantiating polymorphic case?
Adam Megacz wrote: I'm starting to suspect that there are very useful aspects of the parametricity of System F(C) which can't be taken advantage of by Haskell in its current state. To put it briefly, case-matching on a value of type (forall n . T n) forces one to instantiate the n, even though the branch taken within the case cannot depend on n (parametricity). I came up with the simplest example I could and posted it to StackOverflow, but there haven't been any successes (despite some excellent attempts!): http://stackoverflow.com/questions/7720108/ Actually, polymorphism is not implicit in System F, you have to use a big Λ to bind type parameters. For instance, the identity function is written id :: ∀a.(a - a) id = Λa.λ(x::a).x The first argument is the type and the second argument is the actual argument. With this in mind, it's clear that you can't write your example; it would look like this: hard :: ∀n.Maybe (f n) - Maybe (∀n.f n) hard f = case f n of -- n is not in scope Nothing - Nothing Just x - Just (Λn.x) -- n bound here Of course, parametricity tells you that that the function f is actually constant in a certain sense. But to my knowledge, there is no way to make this knowledge internal to System F. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A question about causality in FRP
David Barbour wrote: Alan Jeffrey wrote: A function (f : Beh A - Beh B) is causal whenever it respects =t, i.e. (forall t . a =t b = f a =t f b). Yes. Function outputs only depend on the past values of the input function. Your solutions for double and weird are accurate. Double is lifting the future at each instant into the present, which is obviously not causal. And the `weird` function presumes you already have a obtained a complete view of a behavior at each instant. The `problem` such as it exists: you will be unable to causally construct the argument to the `weird` function, except by modeling a nested/simulated world (i.e. modeling one FRP system within another). This is not an unrealistic endeavor, e.g. one might model the future position of a thrown baseball in order to predict it. In this sense, `weird` is not weird. I concur with that. The function double :: Behavior a - Behavior (Behavior a) double x = const x is not causal because it makes all future values of the behavior x available at once. However, weird :: Behavior (Behavior a) - Behavior a weird = join . fmap (. (+1)) where join a t = a t t is clearly causal as a composition of two causal functions. The point is that the innermost behavior was already available in full, so it's perfectly possible to evaluate it at any time desired. Of course, the function double' x t = \t' - if t' = t then x t' else _|_ is causal. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Lists concatenation being O(n)
Yves Parès wrote: I re-read recently a bit of RealWorldHaskell, and I saw something that puzzles me now that I have a better understanding of the language. It concerns the list concatenation being costful, and the need to use another type like DList. [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) To me, we have here something that would be costful in a strict language, but that here, thanks to guarded recursion ((:) being non-strict), doesn't evaluate the first list until it is needed. How comes RHW says We can see that the cost of creating a new list depends on the length of the initial list, since nothing will be done unless we ask for our list to be evaluated, which is somewhat something we will end up asking. Well, the run-time needed to evaluate an expression depends on how much of the expression you evaluate. If you don't evaluate anything, then you don't need any time. The cost of list concatenation refers to the following fact: Assuming that xs and ys have been evaluated to normal form already, then the cost of evaluating xs ++ ys to normal form is Θ(length xs) reduction steps. For difference lists, the latter cost is only Θ(1). The best way to reason about other demand patterns than normal form is Okasaki's method of attributing a debt to each constructor. See also http://apfelmus.nfshost.com/articles/debit-method.html Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe