FRP* on pyboard



When almost a year ago I watched interesting course Principles of Reactive Programming, I found that many examples of FRP are about circuits and wires. I tried to do something similar to course examples on arduino, but nothing good came, mostly because low expressiveness of Wiring.

And now I trying to do it with pyboard and my microasync library.

First of all, I wrote simple actor (not a really actor, but something similar) for bicolor LED:

from microasync.async import as_chan, do_all
from microasync.device import get_output_pin


@as_chan(Channel)  # now this function returns channel
def get_bicolor_led(chan, left, right):  # `channel` is this actor "mailbox"
    left_pin = get_output_pin(left)  # returns channel for a pin, when we put 1 in that 
    right_pin = get_output_pin(right)  # channel then voltage will be set to 3.3V; when we put 0 - 0V
    while True:
        msg = yield chan.get()  # receive message from a channel
        if msg == 'red':
            yield do_all(left_pin.put(1),  # do commands sequentially
                         right_pin.put(0))
        elif msg == 'green':
            yield do_all(left_pin.put(0),
                         right_pin.put(1))
        elif msg == 'yellow':
            yield do_all(left_pin.put(1),
                         right_pin.put(1))
        elif msg == 'none':
            yield do_all(left_pin.put(0),
                         right_pin.put(0))

This actor is simple to use, for changing color of LED we just need to send (put in channel) red, green, yellow or none:

from microasync.async import coroutine


@coroutine
def test_bicolor_led():
    led = get_bicolar_led('X1', 'X2')
    yield led.put('red')  # switch LED color to red
    yield led.put('green')  # switch LED color to green
    yield led.put('yellow')  # switch LED color to yellow (red and green together)
    yield led.put('none')  # turn off LED

Then I created simple filter for channel, which can be toggled by button on pyboard:

from microasync.async import as_chan, select
from microasync.device import get_switch


@as_chan(Channel)
def switchable_filter(chan, orig_chan, fn):
    # Returns channel from which we can get values from switch and this actor
    # "mailbox", works almost like `select` from golang:
    select_ch = select(get_switch(), chan)
    enabled = False
    while True:
        result_ch, val = yield select_ch.get()
        if result_ch == chan:
            if not enabled or fn(val):  # apply filter if filter enabled
                yield orig_chan.put(val)
        else:
            enabled = not enabled  # toggle filter state

Now I created simple coroutine, which sends red, green, yellow and none to two LEDs sequentially in loop. And when we click button on pyboard we toggle filter, which passess all messages except red to the first LED and only red to the second LED:

from microasync.async import coroutine


@coroutine
def main():
    first_led = switchable_filter(get_bicolor_led('X1', 'X2'),  # creates bicolor led and applies filter
                                  lambda msg: msg != 'red') 
    second_led = switchable_filter(get_bicolor_led('X3', 'X4'),
                                   lambda msg: msg == 'red')
    while True:
        for led in (first_led, second_led):
            for mode in ('red', 'green', 'yellow', 'none'):
                yield led.put(mode)  # sends red, green, yellow, none 

Full source code of example available on github. And video with result:

* not a really FRP, but almost follows The Reactive Manifesto

clj-di: dependency injection for clojure and clojurescript



I was surprised when i found that no one wrote library for dependency injection which works on clojure and clojurescript. I found component, but it’s too complex and not working with clojurescript.

So i developed little library – clj-di. I wrote it using cljx, so library can work with clojure and clojurescript. Library uses atom with hash map for storing dependencies. Dependency can be registered and received using keyword.

Library has two ways for registering dependencies. Permanently with register! (i use it in lein-ring :init for creating db connections):

(register! :db (Database.)
           :logger (get-logger))

And for code block with with-registered (i use it in tests for registering mocks):

(with-registered [:db (Database.)
                  :logger (get-logger)]
  ...)

And two ways for receiving dependency. With get-dep function (useful for receiving single dependency):

(get-dep :db)

And with let-deps macro (useful for receiving more than one dependency):

(let-deps [conn :db
           log :logger]
  ..)

You can see more on github and in documentation.

CSP on pyboard



Lately i worked a lot with clojure and core.async, and i was very impressed with CSP. Mostly because it saves me from js callback hell. For example, js code with sequential http requests (heh, with promises it’s less ugly):

$http.get('/users/').then(function(data){
    return $http.post('/user-data/', data.items);
}).then(function(){
    return $http.get('/posts/');
}).then(function(posts){
    console.log(posts);
});

With clojurescript and core.async it will be:

(go (let [users (<! (http/get "/users/"))]
       (<! (http/post "/user-data/" (:items users)))
       (js/console.log (<! (http/get "/posts/")))))

Clojurescript code looks more readable and simple.

And i developed CSP for micropython in my microasync library.

Example application — servo should rotate to angle which equal to X angle of accelerometer, and user can start/stop app with button:

from microasync.device import get_servo, get_accel, get_switch
from microasync.async import coroutine, loop, Delay, select


@coroutine
def servo_coroutine():
    servo, _ = get_servo(1)  # get_servo returns set and get channels
    accel = get_accel()
    switch = get_switch()
    on = False
    x = 0
    accel_or_switch = select(switch, accel)  # like select from go and like clojure core.async alts!
    while True:
        chan, val = yield accel_or_switch.get()  # like clojure (<! (accel_or_switch))
        if chan == accel:
            x, *_ = val  # we don't need y and z
        elif chan == switch:
            on = not on

        if on:
            yield servo.put(x)  # like clojure (>! servo x)
        yield Delay(0)  # like clojure (<! (timeout 0))


servo_coroutine()
loop()

And recorded on google glass (yep, i bought it few days ago) video of result:

Fixing StackOverflowError on travis-ci when running clojurescript tests



Recently i received strange error when running clojurescript tests on travis-ci:

$ lein2 cljsbuild test
...
Compiling "target/cljs-test.js" failed.
Exception in thread "main" java.lang.StackOverflowError, compiling:(/tmp/form-init311799534829133165.clj:1:89)
	at clojure.lang.Compiler.load(Compiler.java:7142)
	at clojure.lang.Compiler.loadFile(Compiler.java:7086)
	at clojure.main$load_script.invoke(main.clj:274)
	at clojure.main$init_opt.invoke(main.clj:279)
	at clojure.main$initialize.invoke(main.clj:307)
	at clojure.main$null_opt.invoke(main.clj:342)
	at clojure.main$main.doInvoke(main.clj:420)
	at clojure.lang.RestFn.invoke(RestFn.java:421)
	at clojure.lang.Var.invoke(Var.java:383)
	at clojure.lang.AFn.applyToHelper(AFn.java:156)
	at clojure.lang.Var.applyTo(Var.java:700)
	at clojure.main.main(main.java:37)
Caused by: java.lang.StackOverflowError
...

But locally all worked ok. And i found simple solution – increase thread stack size up to 16mb by adding this line to my project.clj:

:jvm-opts ["-Xss16m"]

As a result travis-ci build succeeded.

Switching windows with Leap Motion



After i abandoned my project on Clojure Cup i received little free time on this weekend. And i decided to play with Leap Motion and create little app for switching windows using it.

Result — leaptab. By default app uses win + w for switching windows, but with --use-alt-tab it can use alt + tab.

For opening window switcher (win + w or alt + tab) and switching to window you need to use circle gesture. For selecting window – swipe gesture.

Video with usage of leaptab:

Leaptab tested with ubuntu, but should work on all major platforms, but probably only with --use-alt-tab argument.

let statement in python



Today, when i wrote another context manager, i came up with the idea – write let statement in python using context manager.

First i invented simple realisation, where we manually pass locals:

from contextlib import contextmanager


@contextmanager
def let(locals_, **bindings):
    original = {var: locals_.get(var) for var in bindings.keys()}
    locals_.update(bindings)
    yield
    locals_.update(original)

And usage:

>>> a = 1
>>> b = 2
>>> with let(locals(), a=10, b=20):
...     print(a, b)  # inside `let` scope
... 
(10, 20)
>>> print(a, b)  # outside of `let` scope
(1, 2)

Looks ugly. But we can use little piece of magic with inspect. We can get outer frame and get his locals

from contextlib import contextmanager
from inspect import currentframe, getouterframes


@contextmanager
def let(**bindings):
    frame = getouterframes(currentframe(), 2)[-1][0] # 2 because first frame in `contextmanager` decorator  
    locals_ = frame.f_locals
    original = {var: locals_.get(var) for var in bindings.keys()}
    locals_.update(bindings)
    yield
    locals_.update(original)

Now we don’t need to pass locals explicitly:

>>> a = 3
>>> b = 4
>>> with let(a=33, b=44):
...     print(a, b)
... 
(33, 44)
>>> print(a, b)
(3, 4)

Green threads on pyboard



Some weeks ago i received new fancy device — pyboard. It’s like arduino, but using python instead of wiring. I was little disappointed, because micropython wasn’t have multithreading module.

And i developed microasync — library with green threads for micropython.

Little example, code for toggling leds concurrently:

from microasync.async import loop, coroutine, Delay
import pyb


@coroutine  # decorator for making green thread from function
def toggle_led_on_interval(led, interval):
    while True:
        pyb.LED(led).toggle()
        yield Delay(interval)  # like time.sleep, but non-blocking


toggle_led_on_interval(1, 1)
toggle_led_on_interval(2, 2)
toggle_led_on_interval(3, 1)
toggle_led_on_interval(4, 2)

# start main loop:
loop()

And result:

doto from clojure in python



When i writing code in clojure i can use good macro – doto.

With whom python code like:

window = QMainWindow()
window.setTitle(TITLE)
window.setWindowFlags(Qt.FramelessWindowHint)
window.setAttribute(Qt.WA_TransparentForMouseEvents, True)
window.show()

can be translated in clojure code like:

(doto (QMainWindow.)
      (.setTitle title)
      (.setWindowFlags Qt/FramelessWindowHint)
      (.setAttribute Qt/WA_TransparentForMouseEvents True)
      (.show))

And i wrote hackish class for doing something similar in python.

from functools import partial


class DoTo(object):
    def __init__(self, obj):
        self._obj = obj

    def _do(self, name, *args, **kwargs):
        getattr(self._obj, name)(*args, **kwargs)
        return self

    def __getattr__(self, item):
        return partial(self._do, item)

With method chaining we can emulate behavior of clojure doto:

window = QMainWindow()
DoTo(window)\
    .setTitle(TITLE)\
    .setWindowFlags(Qt.FramelessWindowHint)\
    .setAttribute(Qt.WA_TransparentForMouseEvents, True)\
    .show()