Giter VIP home page Giter VIP logo

yampa's Introduction

Yampa

Build Status Version on Hackage

Domain-specific language embedded in Haskell for programming hybrid (mixed discrete-time and continuous-time) systems. Yampa is based on the concepts of Functional Reactive Programming (FRP).

InstallationExamplesRelated projectsDocumentationContributionsHistory

Features

  • Implements Functional Reactive Programming.

  • Allows for dynamic programs whose structure changes over time.

  • Isolates of effect-free signal functions from effectful actions.

  • Runs fast and is memory efficient.

  • Has been industry tested.

  • Provides a robust, elegant, stable interface.

  • Has well-defined semantics.

  • Supports applicative, functional and arrowized styles.

  • Supports all platforms and enjoys multiple backends.

  • Programs can be tested with QuickCheck and debugged using Haskell Titan.

Table of Contents

Installation

(Back to top)

Pre-requisites

(Back to top)

To use Yampa, you must have a Haskell compiler installed (GHC). We currently support all versions of GHC from 7.6.3 to modern versions (9.X series as of this writing).

On Debian/Ubuntu, the Haskell toolchain can be installed with:

$ apt-get install ghc cabal-install

On Mac, they can be installed with:

$ brew install ghc cabal-install

Compilation

(Back to top)

Once you have a working set of Haskell tools installed, install Yampa from hackage by executing:

$ cabal update
$ cabal install --lib Yampa

Running the following will print the word Success if installation has gone well, or show an error message otherwise:

$ runhaskell <<< 'import FRP.Yampa; main = putStrLn "Success"'

Examples

(Back to top)

Getting Yampa to run is trivial. FRP is about values that change over time. In Yampa, a system is defined by a signal function (SF), which determines how the varying input and the varying output relate.

Code can be written in multiple styles: applicative style, arrowized style, and just plain arrow combinators. All three are compatible and interchangeable.

For example, the following signal function takes a value, integrates it, and then divides that value by the current time:

{-# LANGUAGE Arrows #-}
import FRP.Yampa

signalFunction :: SF Double Double
signalFunction = proc x -> do
  y <- integral -< x
  t <- time     -< ()
  returnA -< y / t

This signal function says that the output signal is the integral y of the input signal x, divided by the time t. The elements between <- and -< are always signal functions (in this case, integral and time are signal functions used to define another signal function).

The example above is written in arrow syntax and uses a Haskell extension called Arrows. If you are unhappy using arrow syntax, you can implement the same behavior using applicative style and/or arrow combinators:

-- Applicative style
signalFunction1 :: SF Double Double
signalFunction1 = (/) <$> integral <*> time

-- Functional style with arrow combinators
signalFunction2 :: SF Double Double
signalFunction2 = (integral &&& time) >>^ (/)

All three are equivalent, and it's a matter of which one you like best.

To run this example, we need to provide the inputs, the times, and consume the output:

firstSample :: IO Double   -- sample at time zero
firstSample =
  return 1.0  -- time == 0, input == 1.0

nextSamples :: Bool -> IO (Double, Maybe Double)
nextSamples _ =
  return (0.1, Just 1.0) -- time delta == 0.1s, input == 1.0

output :: Bool -> Double -> IO Bool
output _ x = do
  print x     -- print the output
  return False -- just continue forever

This is a trivial example, since the integral of the constant function 1.0 over time, divided by the time, is always 1.0! Nevertheless, we are now ready to run!

ghci> reactimate firstSample nextSamples output signalFunction
1.0
1.0
1.0
1.0
1.0
1.0
...

There is a directory with examples, which includes two basic SDL examples and one with using a Nintendo Wii Remote. You can install them with:

$ cabal update
$ cabal install Yampa -fexamples

Related projects

(Back to top)

Games and applications

(Back to top)

  • cuboid: 3D puzzle game with GLUT.
  • Frag: a 3D first person shooting game.
  • hamball: 3D, LAN FPS game of hamster balls flying around and shooting lasers written in Haskell.
  • Haskanoid: a game that uses SDL multimedia, wiimote and kinect. It's cross platform and works in desktop, mobile, and web (compiled with GHCJS).
  • Haskelloids: a reproduction of the Atari 1979 classic "Asteroids"
  • LaneWars: Top-down MOBA game with online multiplayer.
  • MandelbrotYampa: a "hello world" using SDL2, Yampa and OpenGL.
  • Pang-a-lambda: 2D arcade game inspired by the classic super-pang.
  • Peoplemon: a role playing game.
  • Spaceinvaders: Re-write of the classic space invaders.
  • The Bearriver Arcade: A couple of arcade games made using bearriver, a library that implements the Yampa API.
  • Yampa-2048: an implementation of the game 2048 using Yampa and Gloss.
  • Yampa - Game of Life: an implementation of Game of Life using SDL2 and OpenGL.
  • YampaShooter: Top-down team based networked tank game.
  • YampaSynth: Software synthesizer.
  • YFrob: Yampa-based library for programming robots.

A more comprehensive list can be obtained using the reverse dependency finder (http://packdeps.haskellers.com/reverse/Yampa), but only programs uploaded to hackage are listed.

Haskanoid Video Peoplemon by Alex Stuart Space Invaders
Haskanoid, SDL cross-platform arkanoid. Peoplemon, a role playing game Yampa2048, a gloss board game

Use in industry

(Back to top)

Keera Studios uses Yampa to create Haskell games available on Google Play for Android and iTunes for iOS:

Magic Cookies!

Magic Cookies! Video
Copyright © 2015 - 2020 Keera Studios Ltd. All Rights Reserved.
  

Magic Cookies 2!

Magic Cookies 2! Video
Copyright © 2015 - 2022 Keera Studios Ltd. All Rights Reserved.
  

Enpuzzled

Enpuzzled Video
Copyright © - 2017 - Keera Studios Ltd - All Rights Reserved.
  

Keera, Keera Studios, Magic Cookies, Magic Cookies 2, the Magic Cookies logo, the Magic Cookies 2 logo, the Magic Cookies splash screen, the Magic Cookies 2 splash screen, Enpuzzled, the Enpuzzled splash screen, and the Enpuzzled logo are trademarks of Keera Studios Ltd. Google Play and the Google Play logo are trademarks of Google LLC. Apple, the Apple logo, iPhone, and iPad are trademarks of Apple Inc., registered in the U.S. and other countries and regions. App Store is a service mark of Apple Inc.

Backends

(Back to top)

Yampa is backend agnostic, you can ultimately connect it to any backend you want. Existing backends include:

Testing

(Back to top)

Yampa comes with a sophisticated testing library that allows you to use QuickCheck to test your games, and use a time-travel debugger. These features are described in the paper Testing and Debugging Functional Reactive Programming.

You can find the additional projects at:

Other projects

(Back to top)

  • Bearriver: API-compatible Yampa replacement built on top of dunai using Monadic Stream Functions.
  • Dunai: An FRP implementation inspired by Yampa that extends SFs with a monad.
  • Functional Reactive Virtual Reality: a fork of Yampa with extensions for VR.
  • graphui: Attempt to implement Graphui.
  • Haskell-OpenGL-Tutorial same as here: Visually attractive mandelbrot implementation.
  • Keera Hails: Backend for reactive framework with GTK, WX, Qt, Android, iOS and HTML support, with a library to connect Yampa signal functions.

Documentation

(Back to top)

API documentation and tutorials

(Back to top)

The API of Yampa is thoroughly documented on hackage. Documentation is also available in the Haskell wiki page for Yampa.

Publications

(Back to top)

Contributions

(Back to top)

If this library helps you, you may want to consider buying the maintainer a cup of coffee.

Discussions, issues and pull requests

(Back to top)

Discussions

If you have any comments, questions, ideas, or other topics that you think will be of interest to the Yampa community, start a new discussion here. Examples include:

  • You've created a new game or application that uses Yampa.
  • You've written or found a library that helps use Yampa in a particular domain, or apply it to a specific platform.
  • You've written or found a paper that mentions Yampa.
  • You have an idea for an extension that will enable writing programs that are not currently possible or convenient to capture.
  • You think you've found a bug.
  • You want to propose an improvement (e.g., make the code faster or smaller).
  • You have a question.
  • Something in the documentation, a tutorial or a Yampa / FRP paper is unclear.
  • You like the project and want to introduce yourself.

Issues

If a specific change is being proposed (either a new feature or a bug fix), you can open an issue documenting the proposed change here.

If you are unsure about whether your submission should be filed as an issue or as a discussion, file it as a discussion. We can always move it later.

Pull requests

Once we determine that an issue will be addressed, we'll decide who does it and when the change will be added to Yampa. Even if you implement the solution, someone will walk you through the steps to ensure that your submission conforms with our version control process, style guide, etc. More information on our process is included below.

Please, do not just send a PR unless there is an issue for it and someone from the Yampa team has confirmed that you should address it. The PR is very likely to be rejected, and we really want to accept your contributions, so it will make us very sad. Open a discussion / issue first and let us guide you through the process.

Structure and internals

(Back to top)

This project is split in two:

  • Yampa: FRP library.
  • Yampa-test: a testing layer for Yampa.

Yampa's unit tests are mostly implemented as tests inside the yampa-test library. The module hierarchy of yampa-test/tests/Test mirrors that of Yampa.

Yampa also includes some benchmarks as part of the main library. You are encouraged to use them to evaluate your pull requests, and to improve the benchmarks themselves.

A directory yampa/examples contains a number of examples of Yampa programs, some of which can be installed with the flag -fexamples.

Style

(Back to top)

We follow this style guide for the Haskell code and this style guide for Cabal files.

Version control

(Back to top)

We follow git flow. In addition:

  • Please document your commits clearly and separately.
  • Always refer to the issue you are fixing in the commit summary line with the text Refs #<issue_number> at the end.
  • If there is no issue for your change, then open an issue first and document what you are trying to achieve/improve/fix.
  • Do not address more than one issue per commit or per PR. If two changes are not directly related to one another, they belong in different PRs, issues and commits.
  • Document what you did in the respective CHANGELOGs in a separate commit before you send a PR. This commit should be the last one in the PR.
  • If your commit pertains to one package only, name the package at the beginning of the summary line with the syntax <package_name>: <...rest_of_summary...>.
  • Make sure your changes conform to the coding style.

See the recent repo history for examples of this process. Using a visual repo inspection tool like gitk may help.

Versioning model

(Back to top)

The versioning model we use is the standard in Haskell packages. Versions have the format <PUB>.<MAJOR>.<MINOR>(.<PATCH>)? where:

  • <PUB> is just a way to signal important milestones or used for promotional reasons (to indicate a major advancement). A zero on this position has no special meaning.

  • <MAJOR> increases on incompatible API changes.

  • <MINOR> increases on backwards-compatible changes.

  • <PATCH> (optional) increases on small changes that do not affect behavior (e.g., documentation).

History

(Back to top)

This library was created by Henrik Nilsson and Antony Courtney in 2002, while working at Yale's Haskell group, led by Paul Hudak. The design and implementation benefited from frequent discussions with other members of the group, including also John Peterson. From 2008 to 2012, it was maintained by George Giorgidze. In 2014, maintenance was passed to Ivan Perez.

Yampa is the longest standing FRP implementation in Haskell still in use. It has seen and continues to see abundant use in industry, research, and academia. We invite you to be part of this incredible community project as a user, a contributor, and overall supporter.

Yampa is named after the Yampa river in Colorado, USA.

yampa's People

Contributors

appleprincess avatar chriz-zeller avatar craigtreptow avatar eapcochran avatar giorgidze avatar ivanperez-keera avatar jonmouchou avatar madjestic avatar meimisaki avatar mgttlinger avatar ptvirgo avatar ryanglscott avatar sadiejay avatar sigrlami avatar suzumiyasmith avatar thomasvdam avatar ulysses4ever avatar vincibean avatar walseb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

yampa's Issues

Yampa does not build on GHC 7.10

(via Neil Sculthorpe):

Yampa won't install because of the lack of an Applicative instance for Task. (A consequence of the Applicative/Monad proposal.) This is using the latest Hackage version.

[16 of 16] Compiling FRP.Yampa.Task ( src/FRP/Yampa/Task.hs,
dist/build/FRP/Yampa/Task.o )

src/FRP/Yampa/Task.hs:95:10:
No instance for (Applicative (Task a b))
arising from the superclasses of an instance declaration
In the instance declaration for ‘Monad (Task a b)’
Failed to install Yampa-0.9.6

Add a hello world example of gloss + Yampa

It would be great to have some trivial examples of good Yampa that can help people get started.

There's a project called Yampa 2048 that uses gloss. Factorizing the code logic out might give a reasonable hello gloss.

Compile a list of Yampa diagrams

A while back, @lambdor kindly put on his website a list of Yampa diagrams, with sources: http://lambdor.net/?author=1

Over time and after writing several articles, these kinds of diagrams have become pretty useful. However, in order to use them, we need to also be able to credit them properly.

I think it would be great to have a list/table with the images, a link to the svg, and a caption/bibtex entry that credits @lambdor properly.

Henrik Nilsson and Antony Courtney also have some diagrams in dia (what I have been using, mostly), which could also be added.

Haddock documentation for FRP.Yampa.Integration.count

Many functions lack documentation.

One such function is count, which produces a signal carrying an Event with the number of times the input signal was holding an Event.

It would be great if that could be documented ;)

Review/Eliminate Forceable

Yampa defines a Forceable type class that implements one-level-deep NF evaluation. Default implementations are given for tuples and lists.

Instances are also given for Event and other types but, afaict, the main class function force is not used anywhere.

Maybe it should be removed? There's other, more interesting forms of forcing (namely, deepseq).

reactimate's type requirements seem contrived

reactimate seems to have some redundancy in its type requirements, more specifically, the two Bool inputs required for the input and output actions.

Is there a good reason to not introduce some wrapped functions which simplify this? For instance, I wrote a small module, which I've uploaded in this gist (please forgive my naming), which I find I use rather than reactimate directly.

(With regards to issue #15, sReactimate generalises to all monads with no changes, and yampaMain should be is fairly straightforward to adjust for MonadIO actions.)

Should FRP.Yampa re-export all modules

The module FRP.Yampa re-exports individual functions and types. Maybe it should just re-export all modules.

It would be important to check that the API does not change. I don't know if there is an automatic or systematic way of doing this. Maybe browse with ghci, sort the output, and diff?

DatatypeContexts is deprecated

I find that DatatypeContexts appear several times in this project.
(i.e. Point2/3, Vector2/3 and MergeableRecord)

According to this proposal: https://ghc.haskell.org/trac/haskell-prime/wiki/NoDatatypeContexts
DatatypeContexts is deprecated.
It was widely considered a misfeature, and has been removed from the Haskell language.
Although cabal-install makes Yampa buildable even in the latest GHC(by turning the flag on automatically).

Instead, we should use ExistentialQuantification(or GADTs) to add constraints on constructors.
For typeclass deriving, we could enable the StandaloneDeriving for convenience.

Well, actually I'm not sure if DatatypeContexts was necessary in this case.
I'll apologize if I misunderstood the usage here.

Infinite Loop When using (d)pSwitchB

I'm having issues using pSwitchB. I've made a simple program below that demonstrates the issue. When the switch occurs (input value is 3), this goes into an infinite loop, presumably because each time the switch occurs, a new one is immediately triggered. I though using dpSwitchB would solve this problem, but it only delays the issue till the next sample. Am I using (d)pSwitchB incorrectly?

module Main where

import FRP.Yampa

eventAt3 :: SF Integer (Event ())
eventAt3 = arr $ \t -> if t == 3
                        then Event ()
                        else NoEvent

swit :: [SF Integer (Event ())] -> SF Integer [Event ()]
swit actors = pSwitchB
        actors
        (arr (\(_, es) -> () <$ catEvents es))
        (\colSfs _ -> swit colSfs)

main :: IO ()
main = print $ embed (swit [eventAt3]) (0, [(1,Just 1),(1,Just 1),(1,Just 2),(1,Just 3),(1,Just 4)])

Add a hello world example of diagrams + Yampa

It would be great to have some trivial examples of good Yampa that can help people get started.

The ideal diagrams project would be either a Yampa program that outputs an animation (maybe in SVG?), or one that draws the animation using cairo/gtk.

Add count to Yampa's main export list

Somewhere during the module restructuring, I left the function count out. This should probably be exported by FRP.Yampa (it actually broke some projects, apparently).

It's currently with the Integration stuff.

Is it possible to replace the current vector-about modules with the outside one?

I am wondering if it is a better choice for using linear rather than the current vector-about modules.

As can be seen, in the yampa, there are a variety of modules dealing with vectors or vector space. It is obvious that the modules (AffineSpace, VectorSpace, Vector2, Geometry) are not neccesary, for main yampa functions do not closely rely on it.

I have found that the only usage of this and that vector modules is in the Intergration module. If choosing linear as the replacement, the only thing to do is changing the constraints (VectorSpace a s) to the (Additive f, Num a).

Acturely, the similar discussion (http://mailman.cs.yale.edu/pipermail/yampa-users/2012-May/) happened 3 years ago. The main concern for the introduce of a third party vector library is the increase of dependency. Not only in yampa, but in other project the same argument (haskell-game/sdl2#3) existed.

Code is poorly documented

There's a lot of info about Yampa around (papers, haskell's wiki, blogs) but this is not centralised. Since the code is not documented (not using haddock), it's quite daunting to understand the semantics of each function and how to use them.

Create helloworld combining HTML generation and Yampa

Idea: create a Yampa program that generates an HTML file that changes (for instance, a text box that always shows the current mouse coordinate).

Prior knowledge of blaze-html or some other library to generate HTML would be useful.

Create SDL2 demo

It would be nice to add an SDL2 demo so that people know where to start :)

Document Yampa in the wild

Please, comment below and list Yampa projects, and also whether they are maintained (you can tag the maintainer by using their github handle, for example, mine is @ivanperez-keera).

Add top-level documentation

Documentation should be added to the main page. There's tons of it, plus games. This project doesn't even have a README.

Review/Eliminate MergeableRecord

MergeableRecord is not used by any other module. It's an implementation of update operations on records by using type classes. Given the existing work on extensible records & lenses, plus the fact that it's not used, I think it would be best to remove it.

Note: It's exported, so it makes Yampa not backwards compatible.

Unable to build examples bundled with Yampa-0.10.6.1

This is with GHC 8.2.1, if that's significant:

$ cabal get Yampa-0.10.6.1
Unpacking to Yampa-0.10.6.1/
$ cd Yampa-0.10.6.1/
$ cabal configure -fexamples
Resolving dependencies...
Configuring Yampa-0.10.6.1...
$ cabal build
Preprocessing library for Yampa-0.10.6.1..
Building library for Yampa-0.10.6.1..
<build output elided>
Preprocessing executable 'yampa-examples-sdl-bouncingbox' for Yampa-0.10.6.1..
Building executable 'yampa-examples-sdl-bouncingbox' for Yampa-0.10.6.1..
[1 of 1] Compiling Main             ( examples/yampa-game/MainBouncingBox.hs, dist/build/yampa-examples-sdl-bouncingbox/yampa-examples-sdl-bouncingbox-tmp/Main.o )

examples/yampa-game/MainBouncingBox.hs:8:1: error:
    Could not find module ‘YampaSDL’
    Use -v to see a list of the files searched for.
  |
8 | import YampaSDL
  | ^^^^^^^^^^^^^^^

Add description to flags in cabal file

The flags in the cabal file accept a description field that explains what they do.

These could be added and would be shown on the package's hackage page.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.