This page is work in progress. Please do not share yet.
About LambdaCube 3D
Computer graphics programming is a complex task. This complexity is usually hidden in the dark corners of graphics engines. Most of these frameworks, however, either place limitations on the algorithms that can be formulated in them, or make it awkward to express complex relationships. An alternative approach is to build a DSL (Domain Specific Language) which provides access to all GPU features and makes it possible to create better tools. A single unified language is used in place of the OpenGL API and GLSL. This language improves composability and guarantees correctness by compile-time checks, the user can thus focus on creativity instead of the technical details.
For more background information check out the official LambdaCube 3D blog.
LambdaCube 3D Tour
In 2015 we are going on a tour around Europe presenting LambdaCube 3D. Our main motivation is to collect feedback from potential LambdaCube 3D users.
Destinations
| City | Date | Organisation + event link |
|---|---|---|
| Budapest | Monday, May 20, 7:00 PM | Budapest Haskell User Group |
| Munich | Wednesday, May 27, 7:00 PM | Munich-Lambda |
| Zurich | May 29 - May 31 | ZuriHack 2015 – Projects |
| Paris | Tuesday, June 2, 7:00 PM | Functional Programmers Paris |
| London | Friday, June 5, 6:30 PM | London Haskell |
| Cambridge | Wednesday, June 10, 7:00 PM | Cambridge NonDysFunctional Programmers |
| Nottingham | Friday, June 12, 7:00 PM | CompSoc Nottingham |
| London (2) | Wednesday, June 17, 7:00 PM | Mobile and Games Dev |
| Amsterdam | Saturday, June 20, 7:00 PM | FP AMS |
| Berlin | June 23, 24 or 25 | |
| Copenhagen | June 27, 28 or 29 | |
| Göteborg | July 1 or 2 | |
| Stockholm | July 4 or 5 | |
| Helsinki | July 7, 8 or 9 |
Maybe: Tallinn, Riga, Vilnius, Warsaw, Kraków, Bratislava
Presentation Schedule
- Overview of LambdaCube 3D components (approx. 20 min)
- Live coding demo (approx. 20 min)
- Coding dojo (bring your laptop!) (approx. 40 min)
Presenters
- Csaba Hruska
- Csaba is an enthusiastic Haskell programmer. He likes to experiment with cutting edge technologies usually doing it in open source collaboration.
- Péter Diviánszky
- Detto
Participation
Starting with ZuriHac2015, we are open to collaboration. We are happy to share several tasks you can work on, either at ZuriHack or from anywhere in your spare time.
Note: We prefer content licenced under BSD3. When you share content with us not licenced under BSD3, please notify us.
Tasks
- Add or improve demos
- Improve documentation
- Compiler
- …
- …
Please report bugs at the corresponding GitHub repositories.
Overview of LambdaCube 3D Components
Architecture
Components
- DSL for GPU graphics programming
- targets the whole graphics pipeline
- automatic GPU resource management
- strict static typing guarantees all constraints in OpenGL specification
- Integrated Development Environment
- context sensitive editor
- syntax highlighting
- error highlighting
- jump to definitions
- completion
- helpful error messages
- instant visual feedback
- code hot swapping
- context sensitive editor
- Supported platforms
- desktop
- browser
- Documentation
- tutorial with exercises
- demos
- DSL specification
Live Coding Demos
Youtube links
Tutorial
This going to be inteactive.
Coding Dojo Exercises
TODO
Motivations and Goals
The basic motivation for creating LambdaCube is really simple: it represents the perfect intersection of different fields that have excited us for a long time – pure functional programming, computer graphics, and compiler research. We intend to explore a totally new branch of the design space for authoring and developer tools.
Ideally this project would be of interest to people with very different backgrounds. We’re employing some of the latest and greatest bits of type theory – in some ways being a step or two ahead of the newest extensions to Haskell –, but at the same time we’re also aiming to create a friendly, efficient environment for rapidly iterating visual ideas.
We strongly believe in the value of exposing ourselves and others to completely new fields of thought, and approaching them with an open mind. Great discoveries often happen at the boundaries, when a new connection is made – both between the people and the ideas from each side. Only the future can tell whether LambdaCube will have any such impact, but one can always hope!
A Little History
The LambdaCube adventure started in the beginning of 2009, when Csaba decided to create an Ogre3D compatible engine in Haskell. At this time, Gergely was a postgraduate student at BME (Technical University of Budapest) doing research aimed at applying functional programming in various areas – interactive applications and embedded systems –, and he ended up mentoring Csaba over the years thanks to their overlap in interests.
Originally Csaba intended the engine to act as a drop-in replacement for Ogre3D, including the ability to read and display all the existing assets without the need for conversion. The first incarnation of LambdaCube was therefore a traditional rendering engine based on a hierarchical scene graph, offering an essentially C-style imperative API. Around this time we also submitted it to the Jane Street Summer Project program and it ended up as a finalist.
Afterwards, the project went dormant for nearly two years. We did some work under the hood, but only very sporadically as life would deliver its distractions during this period. In mid-2011 we finally released a new version of the engine whose main contribution was defining an actual public API. This required a major clean-up job, but in hindsight the actual improvements were really minor. We basically wrapped all the operations of the engine in an extra monadic layer called LCM (guess what it stands for!), which took care of resource management under the hood. This was also the moment where we switched to the raw OpenGL bindings.
As the announcement for the above release stated, at this point we realised that the direction we had been pursuing was really a dead-end. Trying to shoehorn an imperative API into a purely functional language felt like a constrant struggle against the elements. We went back to the drawing board and came up with a different plan: let’s take inspiration from GPipe and create a purely functional model of the rendering pipeline. We set the goal of creating an independent DSL, but starting to evolve it as a Haskell EDSL at first.
Unfortunately, progress had to slow down due to the team becoming physically separate, as Gergely moved to Finland and became a game developer shortly after the announcement. It took another year before we would reveal the first public version of the new library in the summer of 2012. We also started the LambdaCube3D blog.
The LambdaCube language was designed to be feature complete and safe by construction from the beginning. We deviated from GPipe’s design in a number of ways to achieve this, e.g. by introducing explicit contexts for various rendering phases or defining shaders as explicit functions instead of mapping over streams. We also leverage the type system to encode the constraints of shader languages. As an important design decision, we clearly separate data (geometry) from logic (pipeline), which goes against the long-standing tradition of coupling meshes with materials, but it allows us to describe complex effects and their compositions with surface materials in a modular manner, and makes it easier to implement hot-swapping both for assets and pipelines.
In 2013 we introduced the LambdaCube Intermediate Representation (IR), which was the next logical step on the path to the independent DSL. The IR allows us to separate the frontend and the backend, and ultimately compile a single pipeline description to several platforms.
Work on the actual DSL started in 2014. This was the time when Péter joined the team, first working on our beloved Stunts example, then moving on to the compiler project itself. The last months preceding the big tour in 2015 were spent building the online editing environment.
Vision:
- close to nature work environment
Questions & Answers
These questions were asked by the audience during our tour.
What is the LambdaCube 3D project licence?
The whole project is licensed under BSD3.
What are your long-term goals with the project?
We plan to use LambdaCube 3D for application development.
What kind of applications would you like to develop with LambdaCube 3D?
We decide the subject of our first application after our tour (mid July 2015). It could be a mobile game or a data visualisation tool.
When will be the language stable?
We consider the following phases of completeness (ordered list):
- having a tutorial and documentation
- releases on HackageDB and Stackage
- pilot mobile application written with LambdaCube 3D
After completing these phases, we plan to write more and more applications and validate the language against real world use cases until LambdaCube 3D will be announced stable.
Where can I find the documentation for the language?
There is only a rough language specification at the moment. We plan to add documentation and a tutorial. Get back to the development history to see the progress.
What’s the next big feature to add?
Planned features
- Various language extensions:
RankNTypes,ScopedTypeVariables, typed holes - Compute shaders
- Nested data parallelism
- FRP system
How does this language compare to Elm?
Elm focuses on FRP and web programming. LambdaCube 3D targets computer graphics on multiple platforms.
Elm has a different philosophy regarding language features: be newcomer friendly and avoid advanced type system constructs like type classes and GADTs. On the contrary, LambdaCube 3D aims to use these powerful constructs.
LambdaCube3D try to reuse syntax and type system constructs from Haskell. Elm explores new areas instead.
How is the time input treated in the demos?
The time variable is a Float-typed input value which is supposed to be updated by the user application. Input values are constants during the rendering of a frame.
Conceptually this means that we treat the screen frames as a set of individual images and there is no way to express connection between the images with the type system at the moment. We plan to add some kind of FRP system to LambdaCube 3D which will be reflected in the type of time too.
How do you support debugging?
Currently we use native debugging tools on different platforms. It is possible to add a debugger for the intermediate representation of LambdaCube 3D. It is also possible to add a debugger for the LambdaCube 3D language.
Do you have performance comparisons against C++ and native OpenGL?
We know that performance is crucial for 3D graphics programming. Currently the focus is on language design, later it will shift to compiler optimizations with performance benchmarks.
Is it OK to deal with performance later?
Csaba has experience with doing computer graphics in C++. We keep performance in mind during making design decisions.
Is it possible to get good performance for a high-level language like LambdaCube 3D?
We believe that modern compilers should automate as much boring programming tasks as possible while keeping good performance. You can see LambdaCube 3D as an experiment achieving this goal.
I expect usability errors with structural records plus type classes. Does they play well together?
We don’t have enough experience yet to answer this question. We plan to use structural records more and more in our Prelude and see the consequences.
Why do you develop a separate DSL instead of a Haskell EDSL?
Csaba spent several years with experimenting with a GHC Haskell EDSL, as the previous version of LambdaCube3D was a GHC Haskell EDSL. We switch focus now to experiment with a proper DSL. The pros and cons we considered are listed below. Note that the option is always there to backport the DSL’s innovations to the GHC Haskell EDSL.
Pros
- syntax
- ordinary Haskell functions syntax can be used for shader descriptions
- counterargument: also possible with quasiquoting, although at the expense of some syntactic noise
- syntactic sugar for swizzling
- counterargument: also possible with quasiquoting, although at the expense of some syntactic noise
- ordinary Haskell functions syntax can be used for shader descriptions
- type system
- domain specific error messages
- interactive explanations of errors
- row polymorphism
- counterargument: this may be done with a GHC constraint solver plugin
- runtime system
- should be available in several platforms (in the browser too)
- counterargument: could be solved by replacing the GHC runtime only
- small compiled binaries
- more control on evaluation order
- counterargument: could be solved by replacing the GHC runtime only
- more control on garbage collection
- counterargument: could be solved by replacing the GHC runtime only
- should be available in several platforms (in the browser too)
- other
- easier to experiment with new features
- be lightweight (run also the compiler in the browser)
- more control on sharing of subexpressions
- counterargument: there are several techniques to solve this (but none of them was fully working in our case)
Cons
- one cannot use existing (GHC) Haskell libraries because they won’t work out of the box with the LambdaCube 3D compiler
We see the following options to loosen this argument:- allow to use GHC *.hi files with the LambdaCube 3D compiler
- compile more and more existing GHC libraries out of the box over time with the LambdaCube compiler
- missing GHC toolset (profiling tools, cabal, …)
- missing GHC features (?)
- maintenance costs of a separate parser, type checker and runtime system
Remark: we pay this costs as we go, so the argument is that we might have a fully working system later than with an EDSL - we don’t think that this is the case though
What is the code-base size?
Figures as of 5th June, 2015
| Component | Sources |
|---|---|
| Compiler | 4.6 kLOC Haskell |
| Prelude modules | 0.7 kLOC LambdaCube 3D |
| OpenGL 3.3 backend | 2.7 kLOC Haskell |
| WebGL backend | 1.9 kLOC PureScript |
Dev history
| date | feature |
|---|---|
| 2015.06.04. | Texture support |
| 2015.05.31. | New language features: list comprehension, dot-dot expression |
| 2015.05.29. | New language feature: export lists |
| 2015.05.19. | Initial editor with error highlight, type popups, auto compilation |
| 2015.05.17. | WebGL backend in PureScript |
| 2015.05.16. | New language features: operator precedences; swizzling |
| 2015.05.12. | New language feature: first version of type classes |
| 2015.04.29. | New language feature: type-level literals |
| 2015.04.28. | New language features: type arguments; first version of GADTs |
| 2015.04.13. | OpenGL 3.3 backend in Haskell |
| 2015.04.10. | New language feature: support row polymorphism |
| 2015.04.04. | OpenGL constraints modelled with type families work in the DSL |
| 2015.02.25. | Use System-F as core language |
| 2015.02.14. | First working example in DSL: rotating cube |
| 2015.02.12. | First implementation of compositional typing |
Links
Contact Us
- csaba.hruska@gmail.com
- patai.gergely@gmail.com
- divipp@gmail.com