Can GUI programming be liberated from the IO monad? Functional Reactive
Programming (FRP) promises as much, and I'm trying to make this dream a
reality with my [reactive-banana][] library. Having released version
0.4.0.0, I am now looking for example programs to direct the future
evolution of the library.
Do you know any *small GUI programs* that you would *like* to see
*implemented with Functional Reactive Programming?*
I'm sure that some of you
* are interested in FRP and would like to learn from a few simple but
beautiful examples
* or have written small GUI programs that they are unhappy with because
they were not purely functional
* or have thought about FRP before and concocted a few examples that are
very tricky to implement with FRP
* or have written a nice little GUI application that simply makes a
great example.
I would love to hear your examples, so that I can try to convert them to
FRP style and test my library against them!
Strictly speaking, it doesn't have to be an example with a graphical
interface, I'm also interested in audio and animation examples, though
I'm currently focusing on GUIs.
Here a few examples of what I am looking for:
* I think that Tim Docker's minimal step sequencer [hbeat][] simply
makes a great example. I hope that wxHaskell offers a
platform-independent way to play sound.
* While editing the [Haskell Weekly News][hwn], Brent Yorgey wrote a
little command-line [program to gather newsworthy items][zipedit]. But
wouldn't a GUI be great? Since I'm only interested in the GUI, someone
would have to supply the feed parser for this example to be viable.
Maybe the current editor, Daniel Santa Cruz, might be interested?
* Notes of a musical performance can be modeled as event streams (MIDI),
as Henning Thielemann has [done with great effect][midi streams].
Surely, reactive-banana should be up to the task, but writing an
arpeggiator seems impossible at the moment.
[reactive-banana]: http://hackage.haskell.org/package/reactive-banana
[zipedit]: http://byorgey.wordpress.com/2008/06/21/zipedit/
[hbeat]: http://dockerz.net/twd/hBeat
[midi streams]: http://hackage.haskell.org/package/streamed
[hwn]: http://www.haskell.org/haskellwiki/Haskell_Weekly_News
Best regards,
Heinrich Apfelmus
_______________________________________________
Haskell-Cafe mailing list
Haskel...@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
> Do you know any *small GUI programs* that you would *like* to see
> *implemented with Functional Reactive Programming?*
I may have an example.
> I would love to hear your examples, so that I can try to convert them to FRP
> style and test my library against them!
You want a description of the example, or the complete source code to
make it work ?
Cheers,
David.
I want to hear!
>> I would love to hear your examples, so that I can try to convert them to FRP
>> style and test my library against them!
>
> You want a description of the example, or the complete source code to
> make it work ?
Just a description. :) You can also mention why you find it interesting etc.
That said, I'm mainly interested in the GUI, so if the example includes
elaborate functionality unrelated to GUIs/audio/animation, linking to
the source code would be nice (in imperative style or whatever you have,
I will do the conversion to FRP).
Best regards,
Heinrich Apfelmus
How about a GUI for darcs?
As someone who remains largely uninterested in FRP, I think it's
mainly because toy examples can be done in many different styles
without too much trouble. Even if the style itself is not very nice.
I guess what I'm saying is that I would find "real-world" examples
more compelling. Things that are substantial programs that require
performance analysis, UI design work, etc.
Maybe you can make an example that convinces me :)
More and more things are moving to the cloud these days. Can you make
a web app using FRP?
Jason
Maybe realize on FRP one of following bored examples:
CRUD table: create, update, delete records in table (for example Person records), with validating user input, auto-calculated fields (current age by birth date), totals by column, filtering. I think same GUI tasks get solved many GUI developers in imperative style. I hope solution of such day-tasks in FRP will be elegant
Simple GUI designer (uml-diagrams or reports): very intresting to see FRP approach (events on custom drawing elements, inplace modification of elements)
Best regards,
Dmitriy
This would involve a lot of functionality unrelated to GUIs. Could you
break it down to a minimal "GUI-only" example that still gets the point
across?
> As someone who remains largely uninterested in FRP, I think it's
> mainly because toy examples can be done in many different styles
> without too much trouble. Even if the style itself is not very nice.
> I guess what I'm saying is that I would find "real-world" examples
> more compelling. Things that are substantial programs that require
> performance analysis, UI design work, etc.
>
> Maybe you can make an example that convinces me :)
Oh, but I'm not trying to convince you. Of what interest would your
disinterest be to me? :P
My goal here is to test whether the reactive-banana library can already
swim on its own or whether I need to add new primitives.
> More and more things are moving to the cloud these days. Can you make
> a web app using FRP?
Yes, you can.
Of course, it's not possible/practical to use Haskell as a HTML
scripting language at the moment.
Best regards,
Heinrich Apfelmus
Can GUI programming be liberated from the IO monad?
Heinrich Apfelmus <apfe...@quantentunnel.de> writes:
> Do you know any *small GUI programs* that you would *like* to see
> *implemented with Functional Reactive Programming?*
I don't know if this fits the bill, but a tool that I'd like to see is
plotting for one or more live streams of data. I guess I want something
similar to timeplot, but listening on an input stream and
updating/scrolling the plot. Think 'tail -f /var/log/messages | awk
something | liveplot options'.
-k
--
If I haven't seen further, it is by standing in the footprints of giants
data Person = Person {
name :: String
, age :: Int
, location :: Maybe String
}
I believe this is a good example as this shows converting String -> Int,
and handling values that might or might not exist.
--
Mats Rauhala
MasseR
I wanted to implement a simple game where the player has to escape
from a maze. I didn't have time to look into it, I expect to do
something about it from August. Anyway, I just wanted to post the
idea.
--
Mihai Maruseac
> I want to hear!
> Just a description. :) You can also mention why you find it interesting etc.
Well I have an old program sitting around. Anyway, it's very simple :
The GUI has
- a window with a menu bar, 2 directory selects (source and dest
directories), 1 file select ( the 'patch file'), 1 textview to write
logging information, and a 'Convert' button to start.
- an about window that opens from a 'About...' menuitem
- A status bar.
The convert button stats an action that scans all applicable files in
a source directory, converts them and writes them in a destination
directory.
The conversion itself is irrelevant to the topic, in my case it
consists in searching for patterns in the file and replacing them,
according to a list of changes read from a file, the 'patch file'.
The progression is logged in the textview: file processed, strings
replaced. In the status bar, a percentage bar grows.
Why do I find it interesting ?
Most of the time I would do a program like the above with a command
line interface only. GUI programming can be tedious. Would FRP offer a
way to code such a simple, boring example in a fun way ?
Also, FRP is often concerned with animations, but I'd really like to
see if it works well for small utilities.
I have an old source code I can share, using gtk2hs, imperative style
(and also beginner-ugly style :) ). It's about 200 lines of codes and
a glade file. It just compiled and ran fine here.
This provides another interest. wxHaskell has file dialogs, which are
not events, but instead raw IO actions.
--
Mats Rauhala
MasseR
> Dear Haskellers,
>
> Can GUI programming be liberated from the IO monad? Functional Reactive
> Programming (FRP) promises as much, and I'm trying to make this dream a
> reality with my [reactive-banana][] library. Having released version
> 0.4.0.0, I am now looking for example programs to direct the future
> evolution of the library.
>
> Do you know any *small GUI programs* that you would *like* to see
> *implemented with Functional Reactive Programming?*
>
wxAsteroids[0] seems very well suited for this; it is small and reactive.
It is also well-documented, as Daan Leijen has written a paper[1],
describing this game as a means to show how to use wxHaskell.
Regards,
Henk-Jan van Tuyl
[0] http://www.haskell.org/haskellwiki/WxAsteroids
[1] A Portable and Concise GUI Library for Haskell
http://legacy.cs.uu.nl/daan/download/papers/wxhaskell.pdf
--
http://Van.Tuyl.eu/
http://members.chello.nl/hjgtuyl/tourdemonad.html
--
This has been requested a lot, I like it.
If you could provide me with a tiny Haskell program that fetches a
suitable data source (Yahoo stock prices, MacOS X system data, anything)
and parses it; this would make my job even easier.
Best regards,
Heinrich Apfelmus
This isn't really a specific application, but what I'd like to see most
from FRP is an example of something that involves moving between windows
and dialog boxes. All of the GUI-based FRP examples I've seen so far
involve interactions in a specific GUI layout. It's unclear to me how
FRP extends into a situation like:
- There's a starting window showing several options for what to do
- When the user chooses an option, that window closes, and a new one
opens with that activity.
- In response to some actions, dialog boxes appear with their own
interactions.
It's not clear to me if anyone in FRP has an idea of how stuff like this
fits in. Is there some FRP trick to handle this declaratively? Or
would you just say each move to a new window ends or pauses one network
of events and behaviors, and starts a new one?
--
Chris Smith
Level 1: present a form like the current web form[1] and append the data
to a journal file[2].
Level 2: allow more account posting fields to be added on the fly, for
posting to more than two accounts.
Level 3: populate the account drop-downs with existing account names,
given the api for getting those.
Level 4: provide auto-completion as you type in the account (and description)
fields.
[1] http://demo.hledger.org:5001/register?add=1
[2] http://hledger.org/MANUAL.html#file-format
> Can GUI programming be liberated from the IO monad? Functional Reactive
> Programming (FRP) promises as much, and I'm trying to make this dream a
> reality with my [reactive-banana][] library. Having released version
> 0.4.0.0, I am now looking for example programs to direct the future
> evolution of the library.
This is the request that I was waiting for. :-)
I have some very small wxwidgets example programs that send and receive
MIDI messages via ALSA in order to map, e.g. sliders to MIDI controller
knobs. I must synchronize the value of a slider with a spin widget and
incoming and outgoing MIDI messages and found the way to connect them very
low-level. I would like to see this in a more declarative style.
http://hackage.haskell.org/package/alsa-gui
> * I think that Tim Docker's minimal step sequencer [hbeat][] simply makes a
> great example. I hope that wxHaskell offers a platform-independent way to
> play sound.
I think there are some ways for playing sounds in a portable way, like
'jack' or PortAudio.
> * Notes of a musical performance can be modeled as event streams (MIDI), as
> Henning Thielemann has [done with great effect][midi streams]. Surely,
> reactive-banana should be up to the task, but writing an arpeggiator seems
> impossible at the moment.
Oh, I am addressed explicitly, thanks! Yes, GUI for 'streamed' would be
nice, too. In the meantime I switched from an approach with lazy lists to
one with arrow-like stream processors. This way I could resolve all issues
with wrong timing and inappropriate waiting, but now code looks more
low-level. There are some examples lying around, that I even not started
to implement, because I expect that implementing them in the current
low-level way will yield nasty bugs. Thus I am highly interested in more
sophisticated MIDI stream editor combinators. I expect that inspiration
from other FRP frameworks would help me.
On Jul 8, 2011, at 11:20 AM, Daniel Patterson wrote:
> On Jul 8, 2011, at 3:51 AM, Heinrich Apfelmus wrote:
>> Jason Dagit wrote:
>>> Heinrich Apfelmus wrote:
>>>> Do you know any *small GUI programs* that you would *like* to see
>>>> *implemented with Functional Reactive Programming?*
>>>>
>>>> I would love to hear your examples, so that I can try to convert them to FRP
>>>> style and test my library against them!
>>> How about a GUI for darcs?
>>
>> This would involve a lot of functionality unrelated to GUIs. Could you break it down to a minimal "GUI-only" example that still gets the point across?
>
>
> What about something that just showed the list of patches for a given repository, which would update when the repository changed? That is deadly simple, but could still be somewhat useful (ie, have it track a relatively central repo, and running on a screen somewhere in the metaphorical office). It would also be wonderful to start on a GUI for darcs, and I could say it might interest _me_ in taking a stab at improving it :) And it might be an example of the kind of open system that was mentioned earlier
>
> Daniel
That's a very good example. Unfortunately, I am one of those who don't
have any idea of how stuff like this fits in. :)
I think it's possible to get something like this with pausing and
resuming event networks, but a general and elegant formulation would
probably rely on dynamic event switching, which I haven't attempted to
implement yet. I'm trying to pick the low hanging fruit first.
Best regards,
Heinrich Apfelmus
That's a great example! Keeping track of databases is very common
(emails, reference manager, iTunes, ...), I'll definitely try to
implement an example like this.
> Simple GUI designer (uml-diagrams or reports): very intresting to see
> FRP approach (events on custom drawing elements, inplace modification of
> elements)
I take it that a vector drawing application like InkScape demonstrates
the same concepts? Or this there anything specific to GUI designers?
Best regards,
Heinrich Apfelmus
--
--
Regards,
KC
Just in case you don't already know this, you can use darcs as a
library (take a look at the darcs cabal file).
Jason
Am Freitag, den 08.07.2011, 08:08 +0200 schrieb Heinrich Apfelmus:
> * or have written small GUI programs that they are unhappy with because
> they were not purely functional
I guess this is would be something suitable:
http://www.joachim-breitner.de/blog/archives/292-FrakView-An-Haskell-Renderer-for-Iterated-Function-Systems.html
Small enough, interactive but without any inherent imperativeness, shiny
graphics.
Greetings,
Joachim
--
Joachim "nomeata" Breitner
ma...@joachim-breitner.de | nom...@debian.org | GPG: 0x4743206C
xmpp: nom...@joachim-breitner.de | http://www.joachim-breitner.de/
Well, there is http://www.flapjax-lang.org/ for Javascript FRP.
I don't think it makes much sense to control real-time client-side
interaction by server-side Haskell, the latency is just too big.
Interesting! This looks very much like a command-line program in
disguise, probably a perfect fit for Conal Elliott's tangible values.
http://www.haskell.org/haskellwiki/TV
Could you send me a few screenshots showing the program in action?
Best regards,
Heinrich Apfelmus
:D
>> * Notes of a musical performance can be modeled as event streams
>> (MIDI), as Henning Thielemann has [done with great effect][midi
>> streams]. Surely, reactive-banana should be up to the task, but
>> writing an arpeggiator seems impossible at the moment.
>
> Oh, I am addressed explicitly, thanks! Yes, GUI for 'streamed' would be
> nice, too.
> In the meantime I switched from an approach with lazy lists
> to one with arrow-like stream processors. This way I could resolve all
> issues with wrong timing and inappropriate waiting, but now code looks
> more low-level. There are some examples lying around, that I even not
> started to implement, because I expect that implementing them in the
> current low-level way will yield nasty bugs. Thus I am highly interested
> in more sophisticated MIDI stream editor combinators. I expect that
> inspiration from other FRP frameworks would help me.
Of course, my intention was that you throw away your stream processors
and use reactive-banana for everything. ;D I have made sure that it can
be used both for real-time and for offline computations.
Could you expand a little on your arrow-like stream processors? What do
the arrows look like,
data SF a b = SF (a -> (b, SF a b))
? Which additional primitives did you include, for instance
switch :: SF in (out, Maybe t) -> (t -> SF in out) -> SF in out
delay :: Time -> SF a b -> SF a b
?
And of course, I am particularly interested in the nasty examples that
you came up with. :)
Best regards,
Heinrich Apfelmus
>> Oh, I am addressed explicitly, thanks! Yes, GUI for 'streamed' would be
>> nice, too.
>> In the meantime I switched from an approach with lazy lists to one with
>> arrow-like stream processors. This way I could resolve all issues with
>> wrong timing and inappropriate waiting, but now code looks more low-level.
>> There are some examples lying around, that I even not started to implement,
>> because I expect that implementing them in the current low-level way will
>> yield nasty bugs. Thus I am highly interested in more sophisticated MIDI
>> stream editor combinators. I expect that inspiration from other FRP
>> frameworks would help me.
>
> Of course, my intention was that you throw away your stream processors and
> use reactive-banana for everything. ;D I have made sure that it can be used
> both for real-time and for offline computations.
>
> Could you expand a little on your arrow-like stream processors? What do the
> arrows look like,
>
> data SF a b = SF (a -> (b, SF a b))
>
> ?
My stream processors are not Arrows, because 'first' cannot be
implemented. However, 'arr' and '.' can be implemented.
As far as I understand, the SF banana can only produce an output if an
input event arrives. But my stream processor can set alarms in order to
produce a clock signal. This way they can generate output without any
input.
Currently my stream processors are defined using an explicit state, that
is hidden using an existential quantifier, but of course I would prefer a
Haskell 98 solution.
For example, an arpeggiator stream processor consists of two
functions:
1. Receive key up/down events and keep track of the currently pressed keys.
2. Receive a MIDI controller that controls the tempo of the arpeggiator.
The stream processor sets the alarm according the current tempo
and at every alarm event it sends a single key
chosen from the set of the currently pressed keys.
This example shows, that a stream processor cannot support Arrow.first,
that is extending (arrow a b) to (arrow (a,c) (b,c)), since for an alarm
event, we have no input of type c that could be passed through.
Currently I have build the two tasks into one stream processor. I would
like to split these into two processors. This looks difficult to me, since
the first stream processor (for management of pressed keys) must provide a
state (the set of pressed keys) whenever the second stream processor (for
clock generation) needs it.
> Which additional primitives did you include, for instance
>
> switch :: SF in (out, Maybe t) -> (t -> SF in out) -> SF in out
> delay :: Time -> SF a b -> SF a b
>
> ?
Since I have no Arrow instance I even have to write my own combinators
that are counterparts to (&&&) and friends.
> And of course, I am particularly interested in the nasty examples that you
> came up with. :)
For example I want to write a Guitar simulator: You press a set of keys
together and the processor converts this into successive tones on a
guitar.
Technically I like to do it this way: When a key is pressed, collect all
key press events in the following 10ms. After this period emit all pressed
keys according to a certain pattern. When one of the pressed keys is
released, then send key-press(!) events for all currently pressed keys
according to another pattern. Repeat this cycle. Manage somehow the keys
that are pressed after the first key-down-collecting phase and the keys
that are released during this initial phase. Ignore them or do something
more sensible about them, but make sure that in the output all key-down
events are eventually matched with a key-up event and that for the same
key you never send two successive key-down events or two successive key-up
events. That is, for the same key, key-up and key-down events must
alternate. An exception might be if you receive bogus input. But even
then, the number of key-up and key-down events for one note in the output
shall match, whenever this is true for the input.
For lazy lists you can do time related processing by splitting the list
of events and process the prefix differently from the suffix and then
concatenate the results. This is easy and declarative, but you have no
guarantee that the resulting stream processing is causal and that the
timing is correct. (The second problem arises when merging two event
lists. Merging implies that when waiting for two events then actually the
system waits for the later of the events, but we need to wait for the
first of the two events.)
I can show you how I've been handling this with reactive-banana and
gtk2hs. As a small example, the "File->Open" command is meant to open
a new project. The codez:
> maybeEvent0 :: Typeable a => Action -> IO (Maybe a) -> NetworkDescription (Event a)
> maybeEvent0 act ops = do
> (addHandler, runHandlers) <- liftIO newAddHandler
> liftIO $ on act actionActivated $ ops >>= maybe (return ()) runHandlers
> fromAddHandler addHandler
> -- | Load a saved project file
> openHandler :: ActionGroup -> Window -> NetworkDescription (Event (String, HTree))
> openHandler actGrp _win = do
> act <- liftIO openAction
> liftIO $ actionGroupAddActionWithAccel actGrp act Nothing
> maybeEvent0 act openProjectDialog
> openProjectDialog :: IO (Maybe (String, HTree))
> openProjectDialog = do
> fc <- fileChooserDialogNew (Just "Select a project file")
> Nothing
> FileChooserActionOpen
> []
> fileChooserSetSelectMultiple fc False
> dialogAddButton fc stockCancel ResponseCancel
> dialogAddButton fc stockOk ResponseOk
> widgetShowAll fc
> resp <- dialogRun fc
> case resp of
> ResponseOk -> runMaybeT $ do
> fp <- MaybeT $ fileChooserGetFilename fc
> liftIO $ widgetDestroy fc
> (fp, ) <$> liftIO (readProject fp)
> _ -> widgetDestroy fc >> return Nothing
The `openHandler` function connects the Gtk signal to the
reactive-banana framework. This uses the helper `maybeEvent0`, which
filters an IO action and triggers a reactive-banana Event when that IO
action actually returns a value.
I've been using this pattern for most of my modal dialogs, and I think
it works very well. The one dialog I haven't used it for is the
starting window, which is straight-line imperative code.
I don't yet have any non-modal dialogs or alternate windows, but there
shouldn't be a problem. There's nothing special about which window a
widget is in; it can be connected to the FRP framework just like a
widget in the main window.
John L.
My stream processors are not Arrows, because 'first' cannot be implemented. However, 'arr' and '.' can be implemented.
Currently I have build the two tasks into one stream processor. I would like to split these into two processors. This looks difficult to me, since the first stream processor (for management of pressed keys) must provide a state (the set of pressed keys) whenever the second stream processor (for clock generation) needs it.
Do you know any *small GUI programs* that you would *like* to see *implemented with Functional Reactive Programming?*
Ok, that sounds nasty.
>> And of course, I am particularly interested in the nasty examples that
>> you came up with. :)
>
> For example I want to write a Guitar simulator: You press a set of keys
> together and the processor converts this into successive tones on a guitar.
>
> Technically I like to do it this way: When a key is pressed, collect
> all key press events in the following 10ms. After this period emit all
> pressed keys according to a certain pattern. When one of the pressed
> keys is released, then send key-press(!) events for all currently
> pressed keys according to another pattern. Repeat this cycle. Manage
> somehow the keys that are pressed after the first key-down-collecting
> phase and the keys that are released during this initial phase. Ignore
> them or do something more sensible about them, but make sure that in the
> output all key-down events are eventually matched with a key-up event
> and that for the same key you never send two successive key-down events
> or two successive key-up events. That is, for the same key, key-up and
> key-down events must alternate. An exception might be if you receive
> bogus input. But even then, the number of key-up and key-down events for
> one note in the output shall match, whenever this is true for the input.
The guitar simulator is a great example! And much to my surprise, it's
already possible to implement (parts of) it in reactive-banana 0.4.1! At
least in the real-time version, where we have access to timers from
wxHaskell.
In particular, have a look at the new Wave.hs example, to be found at
the bottom of
http://haskell.org/haskellwiki/Reactive-banana/Examples
It generates a wave-like pattern whenever you click on of the buttons
(strum a chord). When you click two buttons in rapid succession (think
left = key-down, right = key-up), the second wave will not start after
the first one has completed.
(I think this example also makes it clear that it's already to possible
to implement the arpeggiator as you described with timers.)
Of course, the code is not particularly high-level; after all, I am
essentially duplicating event streams as [(Duration,a)]. Then again, we
cannot describe each wave as Event a because we need a notion of "this
event stream has finished" in order to be able to stall the second wave.
In other words, the vanilla Event a is potentially infinite, there
is no way to test whether it has "finished", so *some* other notion is
needed anyway.
Question: how would you actually like to describe the guitar simulator
at a high-level? Did you already wish for some specific combinators?
Assume that you had something like reactive-banana available and imagine
that there were a benevolent djinn granting you three new primitive
combinators of your choice.
Best regards,
Heinrich Apfelmus
If you have arr, (.) and (&&&), then you have first as well:
f **** g = (arr fst >>> f) &&& (arr snd >>> g)
first' f = f **** arr id
Am I missing something here? =)
Cheers,
--
Felipe.
> On Sat, Jul 9, 2011 at 7:58 AM, Henning Thielemann
> <lem...@henning-thielemann.de> wrote:
>> My stream processors are not Arrows, because 'first' cannot be implemented.
>> However, 'arr' and '.' can be implemented.
> ...
>> Since I have no Arrow instance I even have to write my own combinators that
>> are counterparts to (&&&) and friends.
>
> If you have arr, (.) and (&&&), then you have first as well:
>
> f **** g = (arr fst >>> f) &&& (arr snd >>> g)
>
> first' f = f **** arr id
>
> Am I missing something here? =)
I have only something like (&&&), but not precisely (&&&).
I have for instance
parallel :: (Monoid b) => T a b -> T a b -> T a b
The arrow (T a b) emits a value of type 'b' for every incoming event of
type 'a', but may also emit a 'b' without any input trigger.
Monoid.mappend is used to merge the events if both input arrows generate
an output at the same time.
> Question: how would you actually like to describe the guitar simulator at a
> high-level? Did you already wish for some specific combinators? Assume that
> you had something like reactive-banana available and imagine that there were
> a benevolent djinn granting you three new primitive combinators of your
> choice.
If I would know of appropriate combinators, I would just implement them
and not ask the djinn. :-)
Fair enough. :D
How did you do it with lazy lists? The more I think about it, the more I
come to the conclusion that it's impossible to implement this without
duplicating the event data type. As said, the main problem is that you
want a combinator
append :: Pattern -> Pattern -> Pattern
that plays the second pattern (event sequence, the guitar strum) right
after the first one. This means that patterns are *finite*, but this
seems to collide with the requirement that any FRP style Event must be
potentially infinite.
Once you do implement a small DSL for patterns, everything is fine,
though, as the Wave.hs example demonstrates.
Best regards,
Heinrich Apfelmus
A text field which tab-completes words or phrases from a dictionary.
Haskeline provides useful (non-FRP) for implementing this, but it
seems like FRP could handle this in an interesting way.
Tom
Can GUI programming be liberated from the IO monad? Functional Reactive Programming (FRP) promises as much, and I'm trying to make this dream a reality with my [reactive-banana][] library. Having released version 0.4.0.0, I am now looking for example programs to direct the future evolution of the library.
Do you know any *small GUI programs* that you would *like* to see *implemented with Functional Reactive Programming?*
I'm sure that some of you
* are interested in FRP and would like to learn from a few simple but beautiful examples
* or have written small GUI programs that they are unhappy with because they were not purely functional
* or have thought about FRP before and concocted a few examples that are very tricky to implement with FRP
* or have written a nice little GUI application that simply makes a great example.
I would love to hear your examples, so that I can try to convert them to FRP style and test my library against them!
Strictly speaking, it doesn't have to be an example with a graphical interface, I'm also interested in audio and animation examples, though I'm currently focusing on GUIs.
Here a few examples of what I am looking for:
* I think that Tim Docker's minimal step sequencer [hbeat][] simply makes a great example. I hope that wxHaskell offers a platform-independent way to play sound.
* While editing the [Haskell Weekly News][hwn], Brent Yorgey wrote a little command-line [program to gather newsworthy items][zipedit]. But wouldn't a GUI be great? Since I'm only interested in the GUI, someone would have to supply the feed parser for this example to be viable. Maybe the current editor, Daniel Santa Cruz, might be interested?
* Notes of a musical performance can be modeled as event streams (MIDI), as Henning Thielemann has [done with great effect][midi streams]. Surely, reactive-banana should be up to the task, but writing an arpeggiator seems impossible at the moment.
[reactive-banana]: http://hackage.haskell.org/package/reactive-banana
[zipedit]: http://byorgey.wordpress.com/2008/06/21/zipedit/
[hbeat]: http://dockerz.net/twd/hBeat
[midi streams]: http://hackage.haskell.org/package/streamed
[hwn]: http://www.haskell.org/haskellwiki/Haskell_Weekly_News
1. Paul Hudak is writing a new book. http://plucky.cs.yale.edu/cs431/reading.htm
2. It uses FRP and arrows for sound synthesis.
3. It combines FRP signals with monadic (which recently gets
re-written in arrows) GUI composition.
4. New novel techniques is being developed to handle I/O within arrows
framework.
The code can be obtained through darcs, details at
http://plucky.cs.yale.edu/cs431/software_resources.htm
Notably, the way it handles GUI is that the composition of widgets are
static, but the signals flowing between them are dynamic. This closely
follows Conal Elliott's Phooey approach, and greatly reduces the
complexity of GUI programming.
Disclaimer: I was an ex-student who worked on this project.
Regards,
Paul Liu
On Thu, Jul 7, 2011 at 11:08 PM, Heinrich Apfelmus
<apfe...@quantentunnel.de> wrote:
> Dear Haskellers,
>
> Can GUI programming be liberated from the IO monad?
--
Regards,
Paul Liu
Regards,
Paul Liu
For one, I wouldn't consider GUI programming based on HTML as
declarative, since more often than not, the format says nothing about
its behavior, and when it does, it's through javascript, which is
hardly declarative.
Regards,
Paul Liu
On Tue, Jul 12, 2011 at 5:17 AM, James Deng <cnjam...@gmail.com> wrote:
> These days, more and more GUI programming are done in declarative, such as
> HTML(jQuery), Mozilla XUL, android UI XML.
>
> Haskell is an excellent declarative language, so should have the advantages
> of constructing GUI in declarative, intuitive and powerful way. But so far,
> there is not such a GUI library intuitive like Html, powerful like XUL.
>
> I expect something like html to layout GUI, and a haskell GUI engine would
> render the user interfaces files.
> Where is the gap lying?
>
> On 07/12/2011 05:51 AM, Paul Liu wrote:
>
> You guys might want to checkout the recent work on Euterpea at Yale
> CS. In particular:
>
> 1. Paul Hudak is writing a new book.
> http://plucky.cs.yale.edu/cs431/reading.htm
> 2. It uses FRP and arrows for sound synthesis.
> 3. It combines FRP signals with monadic (which recently gets
> re-written in arrows) GUI composition.
> 4. New novel techniques is being developed to handle I/O within arrows
> framework.
>
> The code can be obtained through darcs, details at
> http://plucky.cs.yale.edu/cs431/software_resources.htm
>
> Notably, the way it handles GUI is that the composition of widgets are
> static, but the signals flowing between them are dynamic. This closely
> follows Conal Elliott's Phooey approach, and greatly reduces the
> complexity of GUI programming.
>
> Disclaimer: I was an ex-student who worked on this project.
>
> Regards,
> Paul Liu
>
> On Thu, Jul 7, 2011 at 11:08 PM, Heinrich Apfelmus
> <apfe...@quantentunnel.de> wrote:
>
> Dear Haskellers,
>
> Can GUI programming be liberated from the IO monad?
>
>
> Regards,
> --
> James Deng
> http://cnjdeng.appspot.com
Thanks! Paul Hudak has kindly drawn my attention to Euterpea as well.
> Notably, the way it handles GUI is that the composition of widgets are
> static, but the signals flowing between them are dynamic. This closely
> follows Conal Elliott's Phooey approach, and greatly reduces the
> complexity of GUI programming.
From what I understand, this new approach to I/O for arrows is equal in
expressiveness to the approach I took in reactive-banana .
Best regards,
Heinrich Apfelmus
Many thanks to everyone for telling me of your examples!
I have implemented a few of them:
http://haskell.org/haskellwiki/Reactive-banana/Examples
Overall, the library held up very well, it's already perfectly usable
for implementing GUIs in the functional reactive style. I was
particularly surprised that I was able implement an animation, even
though the library has no notion of time yet! The CRUD/database example
was the most exciting; while still somewhat messy by Haskell standards,
I quite like the result.
Concerning the future evolution of the library, I now have a better
sense of the remaining primitive combinators that are still missing. I
also added a few immediate improvements, like
* MonadFix instance for NetworkDescription
* Overloaded (<@) and (<@>) operators for the `apply` function
and uploaded a corresponding version 0.4.1.0 on Hackage
http://hackage.haskell.org/package/reactive-banana
As said, the library is already very usable. In the future, I hope to
implement more support for animations/audio/time; and then, only dynamic
event switching will be left.