Functional visual programming language with FRP for multimedia
YAVE
is node based visual programming environment with functional reactive programming (FRP).
Disclaimer: This project is still in very early stage!
To play around with YAVE
, you can build from source with standard CMake on Win/Linux.
There are also CI compiled binary artifacts, but these might not work on some environments.
If you have any problem, report issue or ask on gitter.
To build YAVE
, you need compilers which support some features of C++20.
Currently following compilers are used for development:
CMake
is required as build system. VulkanSDK
is also required for graphics.
You should be able to build it with standard CMake
commands.
First build may take much longer to build dependencies.
Procedural content creation with node based visual programming languages are becoming popular in audio and graphics domain because of its flexibility and usability for artists.
In node based languages, you can define how data will be transformed into final output by using data flow graph, which is quite easy to understand even for non-programmers.
However, composing values which change over time (like animations) in node based languages is not trivial. This is because you need to calculate how current time maps to value rather than what kind of operation you want to apply to time related to values. This is different from popular editing paradigm based on declarative time manipulation, which allows you to compose values in the time domain easily.
This has been a known problem in functional programming community, and they found elegant solution by using higher-order functions which commonly known as Functional Reactive Programming (FRP)
. FRP was introduced for declarative programming paradigm for animations, then its target was shifted to real time applications like GUI.
This project is aiming for incorporating original concept of FRP into end user programming environment.
Functional programming
YAVE
supports various functional programming features, including higher-order functions and currying.Reactivity and declarative time manipulation
YAVE
is based on functional reactive programming (FRP). All node functions are internally represented as function over Behaviours (time-varying values).Time.ReTime
is low-level primitive which transform time of value.Animation
nodes, which provide abstraction for values with time interval. You can apply various temporal transformations like scale, extend, concat, merge, etc.Type system
YAVE
is statically typed language.YAVE
is based on classic Hindley-Milner type inference, with some extension to support ad-hoc overloading.Fully interoperable with C++
YAVE
avoids this limitation by implementing functional runtime system as EDSL (embedded domain specific language) on C++.List a
) and implement your own node functions from C++.Note: Nodes in YAVE
takes input from right side and returns to left.
Function nodes represent 'backend' functions. It can be used for either function call (when all arguments are connected) or 'lambda mode' (when there's no input). Lambda mode is used to pass function as value instead of calling it.
Example: Num.Float
, Num.Int
, etc.
Note: YAVE
currently does not have flat lambda introducer like other functional visual programming languages. You always need to create group first, then use it as lambda mode to pass user-defined functions to higher-order functions (this means you always need to use let f x =...
rather than \x ->...
, in analogy to textual languages). Any partially connected nodes are rejected by parser, to simplify syntax for now.
Note: Some function nodes has default values for some sockets which can be changed from GUI. These are treated as connected to invisible node.
Group nodes have multiple roles in YAVE
.
Groups can be used as user-defined functions (same as function nodes), and it also creates its own namespace. Namespaces created by groups can be used as path to find and reference functions from anywhere.
Macro nodes are used to procedurally generate nodes from arbitrary number of inputs. For example, List.List
is macro node which generates tree by List.Cons
and List.Nil
. Macro nodes will be expanded in parser stage.
YAVE
is implemented in C++20 (moving from C++17).
YAVE
's node compiler translates node graph into AST of small functional runtime implemented in C++.
There's no code generation or caching optimizations yet.
Vulkan API is used for graphics backend and user interface.
This project is still in very early stage. There are still lots of things to be implemented.
To-Do list:
Proper engineering as GUI application
Runtime improvements
Type system improvements
Nodes
LGPLv3
Note: These screenshots and gifs can be outdated.