Thursday, February 18, 2010

Trying Factor

Yes, I caved. I picked up yet another language.

This time it's Factor. It's a stack-based language, in the line of Forth and Joy. It's extremely well documented and there are tons of libraries considering how young the language is.

Thinking stack-based is a completely new way of thinking for me, but I'm enjoying it so far.

Of course I had to write my little twitter search application as a testcase. (nice test for libraries and easy of creating glue-code).

I think it's one of the nicer once I've ever written..

Without furter ado, here is it:

! Copyright (C) 2010 Gertm.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs http.client io json.reader kernel prettyprint
sequences ;
IN: twitsearch

CONSTANT: searchurl "http://search.twitter.com/search.json?q="

: make-json ( response data -- x ) nip json> ;

: get-tweet-hsh ( x -- x ) "results" swap at ;

: search ( string -- x ) searchurl
    prepend http-get nip json> get-tweet-hsh ;

: print-with-prefix ( prefix string -- ) append print ;

: print-field ( hsh field prefix -- ) [ swap at ] dip print-with-prefix ;

: print-from ( x -- ) "from_user" "From: " print-field ;

: print-text ( x -- ) "text" ">> " print-field ;

: tweet ( x -- ) [ print-from ] [ print-text ] bi ;

: results ( x -- ) search [ tweet ] each ;


Thanks to the great guys in #concatenative on Freenode, I was able to clean it up a bit and learn some Factor idioms. (Slava, the creator of the language, was one of the guys helping out. Very cool!)

In a way, Factor reminds me a lot of Lisp. I can't explain it yet, but I get the same feel when coding. To me this is a good thing, Lisp was the most fun language I've tried in the past.
It's probably because Lisp was a big influence for Factor.

Let's see how long this new-acquired Factor-Fad lasts ;-)

Wednesday, February 10, 2010

How to use OCamlnet's in_obj_channel and out_obj_channel

No, I still haven't given up on OCaml.. ;-)

Here's a quick howto on how to go from server-ip and port to in_obj_channel and out_obj_channel.
It's really quite simple, but this might save you half an hour of searching:

(* You need these two modules *)
open Netchannels;;
open Netpop;;

(* this function opens a connection to a server with the 
 * Pervasives.in_channel and out_channel
 *)
let open_con server port =
  let server_addr = Unix.inet_addr_of_string server in
  let sockaddr = Unix.ADDR_INET(server_addr,port) in
    Unix.open_connection sockaddr

(* This converts Pervasives channels to 
 * Netchannels.in_obj_channel and out_obj_channel 
 *)
let perv_to_obj (in_c,out_c) =
  let oic = new input_channel in_c in
  let ooc = new output_channel out_c in
    (oic,ooc)

(* the simply use both functions we just wrote to
 * connect with server and port, getting a tuple:
 * in_obj_channel * out_obj_channel as return value
 *)
let open_obj_con server port =
  let channels = open_con server port in
    perv_to_obj channels

I needed this because I want to write some POP3 stuff with the Netpop library.

Hope this helps someone! :-)