Approaches to Functional Programming in Cocos

Hi there.

I’m currently in the initial phases of developing a game, where I want to use an AI module I wrote as a project some years back.

The problem is: the module is written in Scala. It has a lot of immutable-set operations, recursively-defined structures (e.g. propositional logical formulae) and includes a parser. In other words it is the sort of computations that functional programming is great for. I’ve given a few code examples at the bottom to illustrate.

What would be the best way to include functional programming in a cocos2d-x project? I’ve thought of the following approaches:

  1. Re-write the module in F#, and compile as a .dll referenced from the game solution (I’m working on Visual Studio 2013). This should work fine for the win32 compilation of the project, but I am unsure what will happen when deployed to an android or ios device?
  2. Re-write in some other language which may have native cross-platform usage. Haskell? Lisp? Some other alternative? I’m not above learning a new syntax to get this done.
  3. Rewrite the whole module in C++ to include in my game. I would like to avoid this, since it would be a huge pain to translate to another paradigm and would likely become very bloated/hard to understand compared to the current functional syntax. I might be wrong here and it may be possible to write clean and functional code in C++ without me knowing it.
  4. Write in something else and translate to C++. I am unsure how this would work behind-the-scenes and how hard it would be to optimize the code later on, but it may be the way forward. HaskC++ seems to be something along these lines.

My primary problem is that I am simply not proficient enough in what happends deeper inside Cocos2d-x in it’s cross-platform magic to know how much I can stretch it. Can you help? :slight_smile:

Code Examples:

Recursive type-definitions:

class Formula() {
      def and(q:Formula) = Conjunction(this, q) // ∧

      def or(q:Formula) = Disjunction(this,q) // ∨

      def impl(q:Formula) = Implication(this,q) // →

      def not = Not(this) // ¬

      def B(i:String) = Believes(i, this)

      def E(a:Set[String]) = EveryoneBelieves(a, this)
      def C(a:Set[String]) = CommonKnowledge(a, this)
}

Parser:

class mapParser extends RegexParsers {
    
    val disjOp = "|"
    val conjOp = "&"
    val negOp = "~"
    
    val kOp = "B"
    val eOp = "E"
    val cOp = "C"
    val separator = "_"

    val listseparator = ","
    
    def lit:Parser[String] = "[a-z][a-z_0-9]*".r // fluents are never capitalized. but may have underscore.
    def litargs: Parser[String] = repsep(arg,listseparator) ^^ {case list => list.toString.stripPrefix("List").replace(", ",",")}
    def arg = agent | variable
    def args:Parser[List[String]] = leftparen~>repsep(arg,listseparator)<~rightparen
    def argSet:Parser[Set[String]] = leftbracket~>repsep(arg,listseparator)<~rightbracket ^^ { case a => a.toSet }  
    ...

I can tell you the first one will not work. Android and iOS does not support F# (as far as I know)
Basically cocos2d-x multiplatform relies on native support from mobile platforms. This native support is for C++ only, so if you do not program in C++ you will not have native cross-platform. Cocos2d-x also supports scripting bindings: JavaScript and LUA.

If you do not want to port it to C++ I think you have these options:

  • write your module on JS or LUA
  • write bindings or use existing bindings from your language to C++ (like the bindings written for JS and LUA)
  • write another IA logic from scratch

I will give some though to writing in lua or javascript, but if I’m going to manually translate the whole system I might as well do it in C++ - at least there I can overload ++ to avoid writing std::set_union all the time :smile:

I googled a bit about scala to c++ bindings, but as I suspected it seems pretty convoluted. Scala is a JVM language so compiling it to native code isn’t exactly easy.

It seems I will have to re-write it in C++ then. I’ll start looking around for good frameworks for writing parsers. Thank you for your insight.

  • Dan