Functional programming open space

Open space about functional programming

March 15th. Saturday. 20 geeks. 5 sessions in 1-2 tracks. At Madrid on Rails.

Idea and arrangements

I’m quite interested in functional programming, both theory and practice. The initial idea dates back to 2013, when FP Madrid community was created. I simply wanted to gather during all the day and chatter about FP.

In January 2014 I suggested the idea on a FP Madrid meetup. Initial feedback was encouraging, so I chose a date (March 15th) and a venue (Madrid on Rails). By the way, it is hard to find a venue that is: 1. within Madrid city limits, 2. free, 3. open on Saturdays, 4. and open all day.

A week before the scheduled date I got the final confirmation from Estela from Madrid Emprende. I started up the marketing machine – spamming local communities and dusting off my Twitter account. The company I work for, Osoco, provided us with a delicious breakfast (big thank you!). Friday night before the event there was 35 confirmed attendees.

D-Day

marketplace

Finally about 20 fellow programmers made it to the meeting. We started by with the typical introduction about open space principles and rules. After explaining how the schedule was going to be built, there was a round of topic proposals. We filled three tracks, five sessions each. Not a bad result for twenty person group. Though many topics died a natural death due to lack of participants.

Although I facilitated the meeting, I had enough time and energy to attend all sessions of my interest:

  • Intro to Haskell – we went over basic Haskell syntax which I’m still getting used to.

  • Web applications using functional approach – I arrived quite late (we were continuing the Haskell session around the coffee table) and missed the most of discussion. What I proposed was to sketch some Clojure code implementing business logic of some imaginary use cases.

Intro to Haskell

  • Java 8 lambdas – fail; we wanted to do a kata with lambdas. Nobody had JDK8 installed and it was impossible to download it.

  • DDD in Clojure (or in another functional language) – we went through two basic use cases (creation and modification) and wrote some code implementing it with DDD patterns. I felt confused, because I associate DDD with objects having data and behaviour. In Clojure you separate those two into dumb data structures (maps) and functions performing business operations on them (and returning copies of modified data).

  • Category theory – I felt like having a theoretical session about category theory. I struggle to understand it and I wanted to get some tangible examples of categories, arrows and so on. It seemed that everyone was equally confused as me. The conversation shifted to algebraic structures and their counterparts in Haskell. Another question raised was: “do I have to understand all the theory behind functional programming and to be a proficient functional programmer”?

Wrap-up and retrospective

Good open space should close with wrap-up and retrospective. What did we enjoy (or not)? What can be improved in case we, as the community, want to repeat this event?

We did two rounds: personal reflections and a perfection game. Here is the summary of feedback we gathered (I hope I’m not missing any important point):

  • Open the idea marketplace before the event (using a wiki or a more sophisticated tool like Ideascale). It would allow to have more prepared sessions.

  • Not all sessions were run because lack of interest. Voting system with stickers and a reduced number of tracks would have filtered out such sessions.

  • Representations from many communities – FP is a cross cutting paradigm, implemented to lesser or greater extent in a lot of languages. Different backgrounds yield diverse points of view, which enrich discussions.

  • Some more experiences functional programmers expected more engagement from novices (questions, doubts, requests for introductory tutorials). Both parties learn. And this is the purpose of an open space.

  • More facilitation to break the ice at the beginning (I’m the culprit, I was my first facilitation :))

  • Drowsiness after lunch. Maybe we should reduce the duration and finish before (late lunch) – e.g. 9:30 – 14:30 with 4 sessions?

Overall, it was a grateful and enlightening experience for all who sacrificed their Saturday and me as participant and facilitator.

Thanks to

Groovy: Map vs Expando for dynamic data structures

with Expando…

def builder = new Expando(email: 'my email')
builder.make = { println email }
builder.make()

Result:
my email

with Map…

def builder = [email: 'my email']
builder.make = { println email }
builder.make()

Result:
groovy.lang.MissingPropertyException: No such property: email

XML rendering in Grails

Notes taken when researching how to render efficiently a possibly large object tree resulting in complex XML.

Disclaimer: tested with Grails 1.3.7, but it should be valid in more recent framework versions

Convert object to XML string using XML converter

def ping = {
    def result = new Result(response: 'OK')
    def xml = new XML(result)
    render text: xml, contentType: 'text/xml', encoding: 'UTF-8'
}
  • adds explicit <class>…</class> element to the output
  • double transformation – object -> XML string -> ServletResponse output stream
  • relies on poorly documented Grails contracts – here be dragons

Variation – deep conversion

XML.use('deep') {
    def xml = new XML(result)
    render text: xml, contentType: 'text/xml', encoding: 'UTF-8'
}

Variation – customize conversion with a custom marshaller

class ResultMarshaller implements ObjectMarshaller {
    @Override
    boolean supports(object) {
        object instanceof Result
    }

    @Override
    void marshalObject(object, Converter converter) {
        // converter is an instance of XML
        converter.build {
            response object.response
        }
    }
}

class ResultRootElementCustomizingMarshaller extends ResultMarshaller implements NameAwareMarshaller {
    @Override
    String getElementName(o) {
        'wynik'
    }
}

Unit tests

def 'ping, no marshaller'() {
    when:
    controller.ping()

    then:
    XmlAsserts.xmlsEqual controller.response.contentAsString, """<result>
    <class>${Result.name}</class>
    <response>OK</response>
</result>"""
}

def 'ping, marshaller'() {
    given:
    XML.registerObjectMarshaller new ResultMarshaller()

    when:
    controller.ping()

    then:
    XmlAsserts.xmlsEqual controller.response.contentAsString, '<result><response>OK</response></result>'
}

def 'ping, marshaller customizing root element name'() {
    given:
    XML.registerObjectMarshaller new ResultRootElementCustomizingMarshaller()

    when:
    controller.ping()

    then:
    XmlAsserts.xmlsEqual controller.response.contentAsString, '<wynik><response>OK</response></wynik>'
}

Render object to the response using XML converter

def pingConverterRendersToResponse = {
    def xml = new XML(new Result(response: 'OK'))
    xml.render response
}

Unit tests

def 'ping, converter renders to response'() {
    when:
    controller.pingConverterRendersToResponse()

    then:
    XmlAsserts.xmlsEqual controller.response.contentAsString, """<result>
<class>${Result.name}</class>
<response>OK</response>
</result>"""
}

Convert object to XML string using StreamingMarkupBuilder

def pingViaBuilder = {
    def res = new Result(response: 'OK')
    render contentType: 'text/xml', encoding: 'UTF-8', {
        result {
            response res.response
        }
    }
}
  • feature provided by render method
  • direct write into ServletResponse writer
  • could lead to repeated rendering code

Unit tests

def 'ping, direct render'() {
    when:
    controller.pingViaBuilder()

    then:
    XmlAsserts.xmlsEqual controller.response.contentAsString, '<result><response>OK</response></result>'
}

Common objects/helper methods used in examples

class Result {
    String response
}

class XmlAsserts {
    static void xmlsEqual(String actual, String expected) {
        XMLUnit.ignoreWhitespace = true
        def diff = new Diff(actual, expected)
        assert diff.similar(), "${diff.toString()}\nActual XML: $actual\n\nExpected XML: $expected"
    }
}

Instant Markdown book released

I got an opportunity to do the technical review of Instant Markdown book written by Arturo Herrero.
Instant Markdown cover

The book is divided in three parts. First part is about Markdown to HTML processor installation. You can skip it if you won’t generate HTML from manually.

Second part contains the complete language reference in case you want have it at your fingertips. What I miss from this part are examples with a side-by-side comparison of Markdown markup – generated HTML – rendered document, like in many desktop Markdown editors. You would get better grasp of the relationship between Markdown syntax, resulting HTML tags and visual representation of the document.

I enjoyed the third part the most. It tells you about cool applications of Markdown. I already knew GitHub, its comments and readme pages. But there are other useful online services when you can use Markdown to write and publish blog posts and documents.

In short, it is a quick but entertaining reading, like any book from the Instant series. On less that 50 pages, you get a complete Markdown syntax reference and some useful hints.

cut + grep + awk + sed in action; prerequisite: Git repository:

git status -s | \
cut -c4- | \
grep "$test_type.*[Test|Spec]" | \
awk 'BEGIN { FS = "/" } ; { print ($(NF)) }' | \
sed 's/\.groovy//' | tr '\n' ' '

Find all dirty Grails tests

Follow

Get every new post delivered to your Inbox.

Join 373 other followers