Difference between revisions of "Grapefruit"

From HaskellWiki
Jump to navigation Jump to search
(addition of GHC 6.10/Cabal 1.6 info)
(massive reworking)
Line 5: Line 5:
 
== About ==
 
== About ==
   
Grapefruit is a library for creating graphical user interfaces and animated graphics in a declarative way. It contains an implementation of [[Functional Reactive Programming]] and a record system which can be useful in other areas than GUI and graphics programming.
+
Grapefruit is a library for [[Functional Reactive Programming]] (FRP) with a focus on user interfaces. FRP makes it possible to implement reactive and interactive systems in a declarative style. With Grapefruit, user interfaces are described as networks of communicating widgets and windows. Communication is done via different kinds of signals which describe temporal behavior.
   
 
== Features ==
Grapefruit is currently based on [[Gtk2Hs]] but implementations on top of other GUI libraries are planned for the future. By using different GUI libraries on different platforms, Grapefruit shall be able to adapt to local look and feel conventions.
 
   
  +
Grapefruit has the following important features:
Grapefruit makes it possible to implement graphical user interfaces by describing them as systems of interconnected components. Components can be visible components like widgets and windows but also invisible components which provide certain control functionality. Component systems can be built from components by using methods from the <hask>Arrow</hask> and <hask>ArrowLoop</hask> classes.
 
  +
* a push-based FRP implementation where signals
  +
** can be memoized using ordinary variable bindings
  +
** can be merged without doubling of simultaneous events
  +
** cannot behave differently by starting them at different times
  +
* a record system which makes it possible that
  +
** input signals can be left out to get default behavior
  +
** output signals can be left out to ignore uninteresting data
  +
** output signals can be chosen and fetched by pattern matching
  +
* an abstract UI implementation which can work with different backends which in turn use different toolkits to provide different look and feel with one and the same application code
   
  +
At the moment, the only supported UI toolkit is GTK+ (via [[Gtk2Hs]]). We plan to support Qt in the future, making use of the [[HQK]] project’s output.
Components communicate via signals. A signal is either continuous or discrete. A continuous signal denotes a time-varying value. A discrete signal denotes a sequence of values assigned to discrete points in time and can therefore be used to model streams of events. Several functions allow the construction of signals in a purely functional manner.
 
   
  +
== Versions ==
Grapefruit has also support for list signals, special signals denoting time-varying lists where each element has a unique identity. An algebra for list signals provides operations like concatenation, filtering and sorting. The key point is that when the value of a list signal changes, the values of the list signals depending on it do not have to be recalculated completely but can be just updated incrementally.
 
   
  +
Grapefruit has undergone fundamental interface and implementation changes in late 2008 and early 2009. A version without these changes is available as the “classic” version. The classic version contains support for animated graphics, incrementally updating list signals and a restricted form of dynamic user interfaces (user interfaces whose widget structure may change).
User interfaces with a changing collection of widgets are also possible with Grapefruit. There is a special widget which takes a list signal of widgets as its input and always contains the elements of it as its child widgets.
 
   
  +
The current development version does not have these features at the moment. Graphics support is expected to come back later if someone finds the time to port the respective code to the new Grapefruit interface. List signal and dynamic UI support is intended to come back in a much more generalized form.
Furthermore, it is possible to implement animations using graphic signals. These are implemented on top of OpenGL. So-called caching graphic signals are available to make use of OpenGL’s display lists.
 
   
  +
A stable release of Grapefruit is expected to happen at the end of January&nbsp;2009.
With Grapefruit, user interface descriptions always cover the complete lifetime of the respective interface. No explicit event handler registrations and no explicit recalculations of values are necessary. This is in line with the declarative nature of Haskell because it stresses how the user interface operates instead of how this operation is achieved. Internally though, signals are implemented efficiently using the event dispatching and handling mechanism of the underlying GUI toolkit.
 
   
  +
== Download ==
The roots of Grapefruit lie in systems like [[Applications_and_libraries/GUI_libraries#FranTk|FranTk]] and [[Applications_and_libraries/GUI_libraries#wxFruit|wxFruit]]. Grapefruit tries to combine concepts of these systems with new ideas to become a system which maintains a reasonable balance between ease of use and efficiency, and is applicable to real world problems.
 
   
 
The current version can be fetched from the [[Darcs|darcs]] repository at http://softbase.org/grapefruit/darcs/main. If you want to try out the classic version, please get it from the darcs repository at http://softbase.org/grapefruit/darcs/classic.
== Status ==
 
 
As of October 2007, Grapefruit is still in an early stage. Lots of basic concepts are implemented but Grapefruit still lacks a wide variety of widgets, for example. However, adding new widgets shouldn’t be too difficult since Grapefruit provides good generic support for doing this.
 
 
Furthermore, work on formal specification and verification of GUI properties based on Grapefruit’s GUI programming interface and [[Dependent type|dependent types]] has just started. The proof assistant [[Coq]] will be used in this context.
 
 
== Source code ==
 
 
The source code of Grapefruit resides inside a [[Darcs|darcs]] repository under http://softbase.org/grapefruit/darcs/main/. To get a copy, you can use the command <code><nowiki>darcs get http://softbase.org/grapefruit/darcs/main</nowiki></code>.
 
   
 
== Building ==
 
== Building ==
   
You need at least GHC&nbsp;6.8.1 and Gtk2Hs&nbsp;0.9.12.1 to build and use Grapefruit. Currently, Grapefruit is tested with GHC&nbsp;6.8.2 and Gtk2Hs&nbsp;0.9.12.1. For building the API documentation, you need at least Haddock&nbsp;2.0.0.0.
+
You need at least GHC&nbsp;6.10.1 and Gtk2Hs&nbsp;0.9.13 to build and use Grapefruit. GHC&nbsp;6.8.2 can ''not'' be used because of [http://hackage.haskell.org/trac/ghc/ticket/1981 GHC&nbsp;bug #1981]. Gtk2Hs&nbsp;0.9.12.1 might be okay but you would have to change the gtk dependency in grapefruit-ui-gtk/grapefruit-ui-gtk.cabal in order to use it. Grapefruit was tested with GHC&nbsp;6.8.3 and Gtk2Hs&nbsp;0.9.13 as well as GHC&nbsp;6.10.1 and a pre-0.10.0 development version of Gtk2Hs.
   
  +
In addition to Gtk2Hs, you will need a couple of other Haskell libraries. These are all available from [http://hackage.haskell.org/ Hackage]. Cabal will tell you what libraries it wants. Alternatively, you can have a look at the build dependency specifications in the files grapefruit-*/grapefruit-*.cabal.
At the moment, GHC 6.10.1 cannot be used because of the <hask>Arrow</hask> class split. I see no good way to make Grapefruit compatible with both GHC 6.8 and GHC 6.10. If you think, dropping GHC 6.8 compatibility in favor of GHC 6.10 compatibility is good then please tell me. If you think, it’s the other way round then please tell me, too.
 
   
  +
If you get warnings of the form “Can’t find interface-file declaration for type constructor or class …” when compiling grapefruit-ui or grapefruit-ui-gtk with GHC&nbsp;6.8.3 then don’t panic. This seems to be because of a bug in the (non-official) type family support of GHC&nbsp;6.8.3. However, it seems to be harmless.
Grapefruit consists of the following packages, each residing inside a equally-named directory in the source tree:
 
  +
 
Grapefruit consists of the following packages, each residing inside an equally-named directory in the source tree:
 
* grapefruit-frp
 
* grapefruit-frp
 
* grapefruit-records
 
* grapefruit-records
* grapefruit-gui
+
* grapefruit-ui
* grapefruit-graphics
+
* grapefruit-ui-gtk
 
* grapefruit-examples
 
* grapefruit-examples
 
You can use Cabal to build each single package.
 
You can use Cabal to build each single package.
   
  +
There is also a Setup.lhs script in the root directory of the source tree which simplifies the building process. Alas, it only works with older Cabal versions so that it is not usable with the Cabal that comes with GHC&nbsp;6.10.1. For building the complete Grapefruit library (including examples) in place with this script, run the following command:
There is also a script <code>Setup.lhs</code> in the root directory of the source tree which simplifies the building process. (However note that because of Cabal API changes, this script doesn’t work with Cabal 1.6 at the moment.) For building Grapefruit in place, use the following command:<blockquote><p><code>runghc Setup.lhs up-to-register <em>configure-options</em> -- <em>build-options</em> -- --inplace <em>further-register-options</em></code></p></blockquote>If you rather want to install Grapefruit in some directory, use this command:<blockquote><p><code>runghc Setup.lhs up-to-install <em>configure-options</em> -- <em>build-options</em> -- <em>install-options</em></code></p></blockquote>For building the API documentation, you can issue this:<blockquote><p><code>runghc Setup.lhs haddock</code></p></blockquote>This will build the documentation for the different packages with hyperlinks to the [http://www.haskell.org/ghc/docs/latest/html/libraries/index.html Haskell Hierarchical Libraries documentation]. It will also build an index and a contents page for the complete Grapefruit library. The documentation will be placed in the directory <code>doc</code>. The entry point to the documentation will be <code>doc/grapefruit/index.html</code>. For building the documentation, you first need to build the complete library and install it or register it in place.
 
  +
  +
<blockquote><p><code>runghc Setup.lhs up-to-register ''configure-options'' -- ''build-options'' -- --inplace ''further-register-options''</code></p></blockquote>
  +
  +
If you rather want to install Grapefruit in some directory, use this command:
  +
  +
<blockquote><p><code>runghc Setup.lhs up-to-install ''configure-options'' -- ''build-options'' -- ''install-options''</code></p></blockquote>
  +
  +
== Running the examples ==
  +
  +
The package grapefruit-examples of the classic versions provides an executable for each example. Since the current version is able to use different UI toolkits (at least in theory), it would not be wise to create executables since these would be fixed to one specific toolkit. Therefore, in the current version, grapefruit-example provides a toolkit-independent library. To run an example, start GHCi and type the following:
  +
  +
<blockquote><p><code>Graphics.UI.Grapefruit.Circuit.run Graphics.UI.Grapefruit.''YourToolkit''.''YourToolkit'' Examples.Grapefruit.''YourExample''</code></p></blockquote>
  +
  +
At the moment, the only meaningful replacement for <code>''YourToolkit''</code> is <code>GTK</code> and the only meaningful replacement for <code>''YourExample''</code> is <code>Simple</code>.
   
 
== Documentation ==
 
== Documentation ==
   
  +
At the time of writing, Grapefruit lacks documentation seriously. For the current version, documentation should follow very soon. The first official release will most likely contain complete API documentation. There are no plans for providing complete API documentation for the classic version. You will have to live with what’s there. If you have questions, you may always ask the author of Grapefruit as listed in the *.cabal files.
API documentation generated by [[Haddock]] is also on the web. You find it under http://softbase.org/grapefruit/doc/grapefruit/index.html. Note that the documentation might get a bit out of date since it is not automatically regenerated on every commit yet.
 
   
 
== Publications and talks ==
 
== Publications and talks ==
   
  +
The following publications and talks are related to Grapefruit:
 
* Wolfgang Jeltsch: Declarative Programming of Interactive Systems with Grapefruit. [http://www.cs.uu.nl/wiki/Stc Software Technology Colloquium of Utrecht Universiteit]. May 29, 2008.
 
* Wolfgang Jeltsch: Declarative Programming of Interactive Systems with Grapefruit. [http://www.cs.uu.nl/wiki/Stc Software Technology Colloquium of Utrecht Universiteit]. May 29, 2008.
 
** [http://www.cs.uu.nl/wiki/bin/view/Stc/DeclarativeProgrammingOfInteractiveSystemsWithGrapefruit time, place and abstract]
 
** [http://www.cs.uu.nl/wiki/bin/view/Stc/DeclarativeProgrammingOfInteractiveSystemsWithGrapefruit time, place and abstract]
Line 69: Line 87:
 
== Screenshots ==
 
== Screenshots ==
   
Following are some screenshots from example programs using Grapefruit:
+
Following are some screenshots from the examples of the classic version:
 
;Simple
 
;Simple
 
:Clicking on the button adds a star to the caption of the button. This doesn’t look very meaningful. However, Simple is actually a very important example since it demonstrates that feedbacks work—the output of the button is transformed and then used as the button’s input.
 
:Clicking on the button adds a star to the caption of the button. This doesn’t look very meaningful. However, Simple is actually a very important example since it demonstrates that feedbacks work—the output of the button is transformed and then used as the button’s input.

Revision as of 15:34, 22 January 2009


About

Grapefruit is a library for Functional Reactive Programming (FRP) with a focus on user interfaces. FRP makes it possible to implement reactive and interactive systems in a declarative style. With Grapefruit, user interfaces are described as networks of communicating widgets and windows. Communication is done via different kinds of signals which describe temporal behavior.

Features

Grapefruit has the following important features:

  • a push-based FRP implementation where signals
    • can be memoized using ordinary variable bindings
    • can be merged without doubling of simultaneous events
    • cannot behave differently by starting them at different times
  • a record system which makes it possible that
    • input signals can be left out to get default behavior
    • output signals can be left out to ignore uninteresting data
    • output signals can be chosen and fetched by pattern matching
  • an abstract UI implementation which can work with different backends which in turn use different toolkits to provide different look and feel with one and the same application code

At the moment, the only supported UI toolkit is GTK+ (via Gtk2Hs). We plan to support Qt in the future, making use of the HQK project’s output.

Versions

Grapefruit has undergone fundamental interface and implementation changes in late 2008 and early 2009. A version without these changes is available as the “classic” version. The classic version contains support for animated graphics, incrementally updating list signals and a restricted form of dynamic user interfaces (user interfaces whose widget structure may change).

The current development version does not have these features at the moment. Graphics support is expected to come back later if someone finds the time to port the respective code to the new Grapefruit interface. List signal and dynamic UI support is intended to come back in a much more generalized form.

A stable release of Grapefruit is expected to happen at the end of January 2009.

Download

The current version can be fetched from the darcs repository at http://softbase.org/grapefruit/darcs/main. If you want to try out the classic version, please get it from the darcs repository at http://softbase.org/grapefruit/darcs/classic.

Building

You need at least GHC 6.10.1 and Gtk2Hs 0.9.13 to build and use Grapefruit. GHC 6.8.2 can not be used because of GHC bug #1981. Gtk2Hs 0.9.12.1 might be okay but you would have to change the gtk dependency in grapefruit-ui-gtk/grapefruit-ui-gtk.cabal in order to use it. Grapefruit was tested with GHC 6.8.3 and Gtk2Hs 0.9.13 as well as GHC 6.10.1 and a pre-0.10.0 development version of Gtk2Hs.

In addition to Gtk2Hs, you will need a couple of other Haskell libraries. These are all available from Hackage. Cabal will tell you what libraries it wants. Alternatively, you can have a look at the build dependency specifications in the files grapefruit-*/grapefruit-*.cabal.

If you get warnings of the form “Can’t find interface-file declaration for type constructor or class …” when compiling grapefruit-ui or grapefruit-ui-gtk with GHC 6.8.3 then don’t panic. This seems to be because of a bug in the (non-official) type family support of GHC 6.8.3. However, it seems to be harmless.

Grapefruit consists of the following packages, each residing inside an equally-named directory in the source tree:

  • grapefruit-frp
  • grapefruit-records
  • grapefruit-ui
  • grapefruit-ui-gtk
  • grapefruit-examples

You can use Cabal to build each single package.

There is also a Setup.lhs script in the root directory of the source tree which simplifies the building process. Alas, it only works with older Cabal versions so that it is not usable with the Cabal that comes with GHC 6.10.1. For building the complete Grapefruit library (including examples) in place with this script, run the following command:

runghc Setup.lhs up-to-register configure-options -- build-options -- --inplace further-register-options

If you rather want to install Grapefruit in some directory, use this command:

runghc Setup.lhs up-to-install configure-options -- build-options -- install-options

Running the examples

The package grapefruit-examples of the classic versions provides an executable for each example. Since the current version is able to use different UI toolkits (at least in theory), it would not be wise to create executables since these would be fixed to one specific toolkit. Therefore, in the current version, grapefruit-example provides a toolkit-independent library. To run an example, start GHCi and type the following:

Graphics.UI.Grapefruit.Circuit.run Graphics.UI.Grapefruit.YourToolkit.YourToolkit Examples.Grapefruit.YourExample

At the moment, the only meaningful replacement for YourToolkit is GTK and the only meaningful replacement for YourExample is Simple.

Documentation

At the time of writing, Grapefruit lacks documentation seriously. For the current version, documentation should follow very soon. The first official release will most likely contain complete API documentation. There are no plans for providing complete API documentation for the classic version. You will have to live with what’s there. If you have questions, you may always ask the author of Grapefruit as listed in the *.cabal files.

Publications and talks

The following publications and talks are related to Grapefruit:

Screenshots

Following are some screenshots from the examples of the classic version:

Simple
Clicking on the button adds a star to the caption of the button. This doesn’t look very meaningful. However, Simple is actually a very important example since it demonstrates that feedbacks work—the output of the button is transformed and then used as the button’s input.
Grapefruit-screenshot-Simple.png
Codebreaker
This is a Mastermind™-like game. The Add button is enabled if and only if the input field contains a valid code and the display box is enabled if and only if the list of guesses does not contain the code chosen by the computer. These properties are described in a declarative way in the source code.
Grapefruit-screenshot-Codebreaker.png
CircuitingObjects
This example demonstrates Grapefruit’s support for animations.
Grapefruit-screenshot-CircuitingObjects.png