Update
Same old shit. Reading a lot about actor systems and languages lately. Google’s recently announced language, “Go”, sounds interesting as well. At first glance it looks to me like a C with GC, functional constructs, a decent package system, and CSP style concurrency. Will have to check it out more later.
Have also been catching myself writing lots of little toy language interpreters lately…
Just ordered…
A bunch of books off Amazon. Some classics, some geeky stuff, some that are both. When they get here I’ll be happy as a baby in a topless bar.
Unique types and STM?
I had an idea at work.
A given programming language is mostly useful only for masturbation if it cannot support things such as file handles, sockets, pipes, graphics, etc… but these wreck hell on purely functional languages. Monads conceptually work by passing a data structure representing the world between the functions which must alter it, it is happenstance that it is never the same twice. Unique types are a sort of middle ground, a type of data which can only be used once afterwards from which an alternate is derived. Both monads and unique types are syntactically noisier than allowing direct mutation, although Kernel’s clean support for multiple value returns would greatly simplify the handling of uniques. Scheme and Ocaml “solve” it by presuming to be “mostly” functional languages and allow mutation of variables (via refs in Ocaml, set! in Scheme). This is the simplest method but breaks referential transparency a whole lot.
So here’s the question. Why don’t we make those things unique types, and automagically handle their updating in the background managed by something along the lines of STM or the such as is already done for mutable data (ala Clojure)?
Someone steal this idea and implement it or point me to something which already does something similar, or point out some flaws, or whatever. I think it’s a neat idea and would like to know if it’s redundant or for some reason unworkable.
Phone update.
Their sims aren’t interchangeable. Might be ’cause the old phone was a Cingular, before AT&T bought Cingular. Oh well. If I ever give enough of a shit, I’m sure I could find someone with suitable hardware to unlock it.
On the bright … or totally fucking evil… side, I was bitching last night over txts about the phone’s constantly popping up “The last transaction cost you 0.00″ messages with every send/receive, there being no way to get rid of them, and considering getting it unlocked and switching to Verizon or such in the future. Today it seems to have decided of its own accord to nolonger do that.
So either it quits bugging you if the phone’s actually registered with your own name, they’ve quit that annoyance on unlimited accounts, or one of my txts got flagged to be read somewhere.
Just sayin’. All in all, I’m happy enough with it.
Phone fun.
Got a Samsung A177 (prepaid AT&T) on the way home from work today. Mostly got it just for text/IM/etc…, I’ve already got a different AT&T that I use like hell on nights/weekends, which for various reasons I cannot simply add texting to. If I can, however, I intend to ditch the old phone and just swap the sims in the A177 as needed.
I’ve just put it back together (well, I went to add the battery, and the screws were right there… I had to peek…) and finished activating it so now I’m waiting for the $15 credit it comes with to get added to it, after which I’ll add the $15 card I got as unlim texting is $20.
Once I confirm texting works, I’ll attempt the sim swapping.
SMOS
A quick hack, does what I needed it to do. Namely, manage access to ancestor’s methods a little more like YASOS. Maybe someone’ll find it useful.
Perma link for updates and such: http://prael.wordpress.com/smos/
smos.scm
;;;; smos.scm ;;;; Still Macroless Object System. ;;;; This code is still in the public domain. ;;;; No warrany. In fact, I guarantee that even looking at this code will break your shit, leaving you destitute and homeless. ;;;; 0.0.2 ;;;; Broke out vector stuff, in case obj's structure changes later. ;;;; Somewhat YASOS-ify ancestor handling. Ancestors are now stored in a vector. ;;;; (make-method! self some-method (lambda (self) (operate-as self a-number-in-ancestors-vector some-other-method))) ;;;; 0.0.1 ;;;; Initial copy of MOS. ;;;; Object Construction: ;;;; 0 1 2 3 4 5 6 ;;;; #(object-tag get-method make-method! unmake-method! get-all-methods ancestors operate-as) ;;;; Original header: ---------------------------------------------------- ;;; "object.scm" Macroless Object System ;;; Author: Wade Humeniuk <humeniuw@cadvision.com> ;;; ;;; This code is in the public domain. ;;;Date: February 15, 1994 ;; Object Construction: ;; 0 1 2 3 4 ;; #(object-tag get-method make-method! unmake-method! get-all-methods) ;;;; --------------------------------------------------------------------- (define object:tag 'object) (define (obj:tag obj) (vector-ref obj 0)) (define (obj:get-methods obj) (vector-ref obj 1)) (define (obj:make-method! obj) (vector-ref obj 2)) (define (obj:unmake-method! obj) (vector-ref obj 3)) (define (obj:get-all-methods obj) (vector-ref obj 4)) (define (obj:ancestors obj) (vector-ref obj 5)) (define (obj:operate-as obj) (vector-ref obj 6)) (define (object? obj) (and (vector? obj) (eq? object:tag (obj:tag obj)))) ;;; This might be better done using COMLIST:DELETE-IF. (define (object:removeq obj alist) (if (null? alist) alist (if (eq? (caar alist) obj) (cdr alist) (cons (car alist) (object:removeq obj (cdr alist)))))) (define (operate-as obj ancestor-number method) (if (object? obj) ((obj:operate-as obj) ancestor-number method) (error "Cannot access ancestors of non-object: " obj))) (define (get-all-methods obj) (if (object? obj) (obj:get-all-methods obj) (error "Cannot get methods on non-object: " obj))) (define (make-method! obj generic-method method) (if (object? obj) (if (procedure? method) (begin ((obj:make-method! obj) generic-method method) method) (error "Method must be a procedure: " method)) (error "Cannot make method on non-object: " obj))) (define (get-method obj generic-method) (if (object? obj) ((obj:get-methods obj) generic-method) (error "Cannot get method on non-object: " obj))) (define (unmake-method! obj generic-method) (if (object? obj) ((obj:unmake-method! obj) generic-method) (error "Cannot unmake method on non-object: " obj))) (define (make-predicate! obj generic-predicate) (if (object? obj) ((obj:make-method! obj) generic-predicate (lambda (self) #t)) (error "Cannot make predicate on non-object: " obj))) (define (make-generic-method . exception-procedure) (define generic-method (lambda (obj . operands) (if (object? obj) (let ((object-method ((obj:get-methods obj) generic-method))) (if object-method (apply object-method (cons obj operands)) (error "Method not supported: " obj))) (apply exception-procedure (cons obj operands))))) (if (not (null? exception-procedure)) (if (procedure? (car exception-procedure)) (set! exception-procedure (car exception-procedure)) (error "Exception Handler Not Procedure:")) (set! exception-procedure (lambda (obj . params) (error "Operation not supported: " obj)))) generic-method) (define (make-generic-predicate) (define generic-predicate (lambda (obj) (if (object? obj) (if ((obj:get-methods obj) generic-predicate) #t #f) #f))) generic-predicate) (define (make-object . ancestor-list) (define method-list (list)) (define ancestors (list->vector (cons 'i-wish-self-could-go-here-but-i-dont-have-macros ancestor-list))) (define num-ancestors (length ancestor-list)) ; I can't seem to (vector-length ancestors) here. (define (operate-as obj-num method) (method (vector-ref ancestors obj-num))) (define (make-method! generic-method method) (set! method-list (cons (cons generic-method method) method-list)) method) (define (unmake-method! generic-method) (set! method-list (object:removeq generic-method method-list)) #t) (define (methods) method-list) (define (get-method generic-method) (let ((method-def (assq generic-method method-list))) (if method-def (cdr method-def) (let loop ((current-ancestor 1)) (if (> current-ancestor num-ancestors) #f (let ((method-def ((obj:get-methods (vector-ref ancestors current-ancestor)) generic-method))) (if method-def method-def (loop (+ 1 current-ancestor))))))))) (vector object:tag get-method make-method! unmake-method! methods ancestors operate-as)) ;; Samples: ;; SMOS/MOS: ;; ;; > (define name (make-generic-method)) ;; > (define job (make-generic-method)) ;; > (define (person n) ;; (define self (make-object)) ;; (make-method! self name (lambda (self) n)) ;; self) ;; > (map name (list (person 'bob) (person 'ashley) (person 'george))) ;; (bob ashley george) ;; > (define (worker n j) ;; (define self (make-object (person n))) ;; (make-method! self job (lambda (self) j)) ;; self) ;; > (map name (list (worker 'bob 'mechanic) (worker 'ashley 'pilot) (worker 'george 'loanshark))) ;; (bob ashley george) ;; > (map job (list (worker 'bob 'mechanic) (worker 'ashley 'pilot) (worker 'george 'loanshark))) ;; (mechanic pilot loanshark) ;; > ;; SMOS operate-as: ;; ;; > (define name (make-generic-method)) ;; > (define is (make-generic-method)) ;; > (define job (make-generic-method)) ;; > (define really (make-generic-method)) ;; > (define (person n) ;; (define self (make-object)) ;; (make-method! self name (lambda (self) n)) ;; (make-method! self is (lambda (self) 'person)) ;; self) ;; > (define (employee n j) ;; (define self (make-object (person n))) ;; (make-method! self job (lambda (self) j)) ;; (make-method! self is (lambda (self) 'slave)) ;; (make-method! self really (lambda (self) (operate-as self 1 is))) ;; self) ;; > (name (employee 'bob 'mechanic)) ;; bob ;; > (is (employee 'bob 'mechanic)) ;; slave ;; > (really (employee 'bob 'mechanic)) ;; person (define name (make-generic-method)) (define is (make-generic-method)) (define job (make-generic-method)) (define really (make-generic-method)) (define (person n) (define self (make-object)) (make-method! self name (lambda (self) n)) (make-method! self is (lambda (self) 'person)) self) (define (employee n j) (define self (make-object (person n))) (make-method! self job (lambda (self) j)) (make-method! self is (lambda (self) 'slave)) (make-method! self really (lambda (self) (operate-as self 1 is))) self) (name (employee 'bob 'mechanic)) (is (employee 'bob 'mechanic)) (really (employee 'bob 'mechanic))
ParrotVM
Makes my pants uncomfortable. Register based, tail call optimizing, supports call/cc(!), has the beginnings of JIT compilation… the GC isn’t exactly bleeding edge but at least isn’t one of the stop-the-world sorts (something about 3 color marks and a background thread doing incremental sweeping IIRC), and like the layout algorithms in xmonad it is easy to replace with something better when one comes around. Oh yeah, and threading. Decent looking FFI. The promise of calling libs from other languages in the future (like the way OCaml can talk to any Perl module from CPAN). And it reached 1.0 with a stable API recently. And interestingly there seems to be talks about working along side the LLVM folk…
There’s just a lot of cool shit going on here. Whereas Java/.Net are trying to bolt in the infrastructure to support dynamic languages, Parrot’s designed from the ground up to do this.
Perhaps GC wouldn’t matter much if something like newLISP with its funky one reference only “GC” were ported to it… on that note I should try to compile newLISP to LLVM bytecode.
And Java’s planning (apparently) on supporting TCO and if it already did, so would Clojure (the recur thing just drives me loopy, pun intended), and I probably never would have noticed Parrot.
For that matter, Clojure on Parrot would rock my balls too. And there’s word of Parrot eventually maybe understanding JVM/.Net bytecode… shouldn’t be much of a tweak from there…
You know? A few months ago I found myself wishing I had been born in the 60’s or 70’s, so I could have been around when all of the cool Lisp stuff was happening. I think I’ve changed my mind… this is a fucking awesome time to be here.
And as long as my ParrotVM post has turned into an obscure Lisp post, I should mention Arc. Arc is a Lisp. There, I mentioned it. Now let’s never speak of that again.
Who wants a non-toy R5RS Scheme on the Parrot VM?
So do I, go write me one. Here’s how (I hope):
pre-scheme is essentially a lispy-syntax C, complete with memory allocations, freeing, goto, minimal TCO, no GC… basically disgusting from a (this, anyway) lisper’s POV, and a far cry from the shear sexiness of R5.
The interesting thing about it though (other than making C a saner language) is that Scheme48’s VM is implemented via Scheme48’s pre-scheme->C translator, which as it happens, in true Lisp fashion, is itself implemented in Scheme. And I’d imagine implementing the minimalistic pre-scheme to be a far sight easier than implementing all of R5. You can look at the Scheme48 distribution’s makefile to see how to go about getting pre-scheme loaded to play with.
It may be a weird way to go about it, running a stack based VM atop a register based one (let alone one wanting malloc/free), but I’d think it to be the quickest route towards non-toy R5 on Parrot, and if nothing else a sufficient stop-gap until “native” implementations approach practical usability. Plus you already have most of your test suite for free.
Of course I havn’t looked into this in any depth, particularly what the Parrot implementation of pre-scheme would need to do other than parse the syntax. And I don’t really have the time to. So I thought I’d toss the idea out there and see if anyone else picks it up. What the hell, it’s worth a shot right?
I’m still alive.
Has been busy around here lately.
SoLoad: Enough FFI to get the job done.
Process based pseudo FFI. Fucking awesome. I had been doing similar stuff with tclsh and wish via snow’s tk package to take advantage of TCL libraries, but this looks to be much much nicer and provides access to C libs.
If you don’t need callbacks or worry much about continuations, this should save a great deal of headache. And if you do, well, a few scheme implementations support SWIG anyway.
SoLoad intro
SoLoad basic
SoLoad intermediate
SoLoad at Launchpad
SoLoad wiki
-
Recent
-
Links
-
Archives
- November 2009 (1)
- October 2009 (1)
- August 2009 (1)
- July 2009 (3)
- April 2009 (2)
- March 2009 (1)
- December 2008 (1)
- November 2008 (1)
- September 2008 (1)
- July 2008 (5)
- June 2008 (8)
- April 2008 (3)
-
Categories
-
RSS
Entries RSS
Comments RSS