Jon Aquino's Mental Garden

Engineering beautiful software jon aquino labs | personal blog

Tuesday, March 04, 2014

Lisphp at Ning - Introduction

At Ning, we are experimenting with Lisphp, which allows us to call Lisp from PHP and vice versa. It's like an oasis of functional programming in the midst of PHP.

There isn't much on the web on Lisphp, so I am writing some blog posts (in my Lisphp category) about my experiences with it.

First, some helpful resources:

You'll notice that Lisphp does not come with any documentation other than what is on the Github page. A list of all the functions is in the Environment.php file. Here are brief descriptions of what some of the functions do:

  • define - defines a function or global variable
  • let - sets local variables
  • let* - sets local variables - the definitions can refer to each other
  • setf! - sets a local variable in an "imperative" style: (setf! foo 5). For setting local variables, prefer let first, followed by let*, followed by setf!
  • lambda - creates an anonymous function
  • apply - applies a function to an array of arguments
  • list - creates a Lisphp list: (list) or (list 'a' 'b' 'c')
  • array - creates a PHP array: (array) or (array 'a' 'b' 'c')
  • do - executes code several times in a loop
  • car - returns the first item in a list: (car flavors)
  • cdr - returns the remaining items in the list (i.e., not the first one): (cdr flavors)
  • at - returns the value at the given key: (at flavors 'key')
  • set-at! - sets the value at the given key: (set-at! flavors 'key' 'value')
  • unset-at! - unsets the value at the given key: (unset-at! flavors 'key' 'value')
  • exists-at? - does isset() on the value at the given key: (exists-at? flavors 'key')
  • count - returns the number of items in the list: (count flavors)
  • map - applies a function to every item in a list
  • filter - filters out items from a list
  • fold - (aka "reduce") goes through a list to create a single value
  • if - if statement
  • cond - switch statement
  • = - ==
  • == - ===
  • !=, !==, <, >, <=, >=, +, -, /, *, %, not, and, or, nil, true, false
  • . - concatenates strings
  • isa? - returns whether the object is an instance of the given class: (isa? foo <ArrayObject>)
  • string - strval()
  • substring - substr()
  • string-upcase - strtoupper()
  • string-downcase - strtolower()

I'm not sure about the following - if you know, let me know:

  • eval
  • quote
  • symbol
  • macro
  • dict - I'm not exactly sure how this works. I made a replacement called "hash"—see below.

I also added the following custom functions - I'll give the code in my next blog post:

  • import: imports a lisp file: (import 'foo/bar/baz.php')
  • php: runs a PHP function without having to import it: (php :htmlentities 'foo')
  • cons: prepends an item to an array: (cons 'strawberry' flavors)
  • hash: creates an array of key-value pairs: (hash 'key1' 'value1' 'key2' 'value2')
  • array-set: sets an item on a multidimensional array: $flavors['foo']['bar'] = 'baz' is (array-set flavors 'foo' 'bar' 'baz')
  • array-get: gets an item from a multidimensional array: $flavors['foo']['bar'] is (array-get flavors 'foo' 'bar')
  • arr: array_replace_recursive()
  • environment: this is the Lisp environment itself added as a variable, to allow you to check if a function exists: (exists-at? environment 'my-function')

Finally, some tips:

  • See if your editor has a plugin that will automatically indent your Lisp code. For example, Sublime Text has a lispindent plugin that will indent your code whenever you press Enter; you can also press Command+I to re-indent the selected code.
  • Sometimes you may need to dive into the Lisphp code to fix things. This is a good opportunity to learn how Lisphp works, and to contribute back by submitting a pull requests. I submitted two pull requests and they were accepted immediately.
  • To import a constant: (use +XG_Model::PLAINTEXT+). Now you can reference +XG_Model::PLAINTEXT+.


Post a Comment

<< Home