Go Down

Topic: Juniper – A new functional reactive programming language for the Arduino (Read 1 time) previous topic - next topic

calebh

I'd like to introduce Juniper, a new high level functional reactive programming language for the Ardunio.

http://www.juniper-lang.org/

Not only does functional programming allow for strong scalability of compact, readable and effective code, but functional reactive programming is specifically designed to handle timing based events in an intuitive way. Juniper is designed to carry these advantages, as well as be lightweight enough to function viably on the Arduino.

Juniper supports many features typical of functional programming languages, including algebraic data types, tuples, records, pattern matching, immutable data structures, parametric polymorphic functions, and anonymous functions (lambdas).

Some imperative programming concepts are also present in Juniper, such as for, while and do while loops, the ability to mark variables as mutable, and mutable references.

Robin2

Just out of curiosity I have looked at your link and at the HelloWorld tutorial.

The explanation of the tutorial is surprisingly well written.

But even after reading it the whole thing seems more complicated than C/C++

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

pYro_65

Just out of curiosity I have looked at your link and at the HelloWorld tutorial.

The explanation of the tutorial is surprisingly well written.

But even after reading it the whole thing seems more complicated than C/C++

...R
I agree, it is a very confusing syntax. At over 15 years in-depth programming experience, I can usually absorb the basics of a language before having to dive in the manual. Whereas Juniper seems to have a relatively steep learning curve just to simply begin.

Also I think the claim that C++ is low level to justify Juniper is quite a naive statement. Its raw to the metal C-style access does not detract from the high level features designed into C++.  Some people complain that it hides to much low level features (classes, interfaces,...), but in reality they are both there in full swing.

However, that being said, as this is your university project that will one day land you a dream job, then congrats, you've done nice work.

However all non C++ languages (for Arduino) will suffer as a success unless they support the pre-built libraries. Yes these languages 'may' turn out to be easier to write a statement (the standard blink sketch is far smaller than the Juniper version), however, the ease is moot if people have to write everything from scratch.

Arduino works well because of the extensive amount of libraries. The amount of code to learn is minimal, people can get something working, tweak it, and be happy, while still not really understanding what is going on.
Forum Mod anyone?
https://arduino.land/Moduino/

calebh

Juniper 2.0.0 has just been released! New features include type inference and a complete overhaul of the parser.

calebh

Juniper 2.2.0 has been released! Also the presentation given at FARM is now on the Juniper website:
http://www.juniper-lang.org/

pYro_65

Juniper 2.2.0 has been released! Also the presentation given at FARM is now on the Juniper website:
http://www.juniper-lang.org/
I like how you take a standard blink example in C++, then claim it to be hard to understand. Then you show a Juniper version which is supposed to be simple... really, just really???

I doubt you have consulted beginners of Arduino in this at all. You have taken a simple blink without day example and turned it into something very unintuitive. There is no way your code is simpler than basic well defined statements.

if
pinMode()
millis()
digitalWrite()


Code: [Select]
module Blink
open(Prelude, Io, Time)

let boardLed = 13

let tState = Time:state()
let ledState = ref low()

fun blink() = (
    let timerSig = Time:every(1000, tState);
    let ledSig =
        Signal:foldP(
            fn (currentTime, lastState) ->
                Io:toggle(lastState)
            end,
            ledState, timerSig);
    Io:digOut(boardLed, ledSig)
)

fun setup() =
    Io:setPinMode(boardLed, Io:output())

fun main() = (
    setup();
    while true do
        blink()
    end
)


Congratulations on getting it going though, but it is definitely not a beginners tool.
Forum Mod anyone?
https://arduino.land/Moduino/

calebh

I like how you take a standard blink example in C++, then claim it to be hard to understand. Then you show a Juniper version which is supposed to be simple... really, just really???

I doubt you have consulted beginners of Arduino in this at all. You have taken a simple blink without day example and turned it into something very unintuitive. There is no way your code is simpler than basic well defined statements.

if
pinMode()
millis()
digitalWrite()


Code: [Select]
module Blink
open(Prelude, Io, Time)

let boardLed = 13

let tState = Time:state()
let ledState = ref low()

fun blink() = (
    let timerSig = Time:every(1000, tState);
    let ledSig =
        Signal:foldP(
            fn (currentTime, lastState) ->
                Io:toggle(lastState)
            end,
            ledState, timerSig);
    Io:digOut(boardLed, ledSig)
)

fun setup() =
    Io:setPinMode(boardLed, Io:output())

fun main() = (
    setup();
    while true do
        blink()
    end
)


Congratulations on getting it going though, but it is definitely not a beginners tool.

Anyone who is familiar with functional programming should be very comfortable with programming in Juniper.

In the interest of simplicity, I have further reduced the blink example for you:
Code: [Select]

module Blink
open(Prelude, Io, Time)

let tState = Time:state()
let ledState = ref low()

fun main() = (
    Io:setPinMode(13, Io:output())
    while true do (
        Time:every(1000, tState) |>
        Signal:toggle(Io:low(), Io:high(), ledState) |>
        Io:digOut(13)
    ) end
)


Note that this code is fully concurrent without any additional work by the programmer.

Now you may be correct that using millis is simpler than Juniper for a blinking LED. But consider what happens when you add additional sensors and outputs, such as buttons, accelerometers, LEDs lighting up at different intervals, etc. Unfortunately, if you use millis you must explicitly schedule all of these events.

The paper and presentation make these key observations about the current state of Arduino programming:

  • Functions that use delay() do not compose
  • Combining concurrent activities with the current style of writing Arduino code requires explicit scheduling, leading to significant cognitive overhead for the programmer.
  • Any reasonably sophisticated program for the Arduino consists of an ad hoc event scheduler and finite state machine(s).
  • The current style of programming the Ardunio makes it difficult to decouple the timing (event scheduler) logic from the rest of the code. This quickly leads to the infamous problem of "spaghetti code."


Here's a nice quote from the paper:

Quote
In this paper we present a new language, Juniper, for programming Arduinos and similar microcontrollers. We leverage the observation that many Arduino programs are reactive: they respond to incoming signals, process those signals, and generate new output signals. Using the existing C++ environment, these programs quickly turn into "spaghetti" code that lacks modularity and is difficult to reason about. Juniper solves this problem by using functional reactive programming (FRP). In FRP, the program reacts to events by propagating values along signals or behaviors in a directed graph. Signals and behaviors can be thought of as time varying values in the program. Nodes in the directed graph represent functions which map signals to new signals. Independent parts of the signal graph can run asynchronously, providing concurrency without any additional work by the programmer. Higher-order functions, such as map, fold, and filter, provide another level of expressive power and reuse.
So essentially Juniper provides a higher level of abstraction than is currently used in Arduino programming. Is this harder for beginners to learn? Probably, since this is the nature of abstraction. Only once the abstraction is understood can its power be appreciated.

shahh

I have been working on ardinuo to run three functions in parallel for my final masters thesis. Actually I am getting some inputs like voltages and currents then using them in my functions i.e. current control and voltage droop control.

I have my code written using FreeRTOS but I want to improve the functionality or you can say more efficient execution of tasks in parallel.

Anyone can suggest whether functional reactive programming i.e. Juniper would be good for such a pseudo-parallel programming? It would be highly appreciable if any idea to use FreeRtos library functions to achieve prioritization of tasks.

Robin2

Anyone can suggest whether functional reactive programming i.e. Juniper would be good for such a pseudo-parallel programming? It would be highly appreciable if any idea to use FreeRtos library functions to achieve prioritization of tasks.
I have no idea. I just use the simple technique in Several Things at a Time

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up