Skip to content

A prototype-like object system based entirely on functions.

Notifications You must be signed in to change notification settings

eduardoejp/jormungandr

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 

Repository files navigation

jormungandr

A prototype-like object system based on functions.

Motivation

Nothing practical really. I just figured that since people have already built functional programming on top of OO (e.g. Clojure), I might as well build OO on top of FP.

Why a prototype-like OO system? I believe those are the only true object systems, since there are only objects and no classes.

That said, in jormungandr you don't do prototype inheritance by setting a "proto" attribute or something like that. Being functional in nature, objects are immutable, so you inherit by simply modifying objects and working with the new copies.

Usage

To get it, add this to your leiningen dependencies [jormungandr "0.1.0"]

To use the library, add this to your code: (use jormungandr). Don't worry about the symbols being interned. There are only 2: object, a function; and ->1, a macro.

This is object's signature: (object [& [attrs methods]]) You can create new objects by passing this function a map of attributes and a map of methods. Method names should be keywords, but they can really be anything. The functions mapped to them must always take the object itself as their first argument.

You invoke methods like this: (some-object :some-method arg1 arg2 ... argN)

Objects come with various basic operations by default. You invoke them just like you would a method. These are the operations and their signatures:

(obj :$get k)                 ;; Basic getter.
(obj :$set k v)               ;; Basic setter.
(obj :$unset k)               ;; Basic unsetter (the equivalent to Clojure's dissoc).
(obj :$has? k)                ;; The equivalent to Clojure's contains?.
(obj :$attrs)                 ;; Gives you a list of attributes.
(obj :$recall method)         ;; Given a method's name, returns the associated function.
(obj :$learn method function) ;; Adds a new method.
(obj :$forget method)         ;; Removes old method definitions.
(obj :$knows? method)         ;; Like :$has?, but for methods.
(obj :$knowledge)             ;; Like :$attrs, but for methods.

The ->1 macro is like the -> macro we're all familiar with, except that it puts the items at the head of the list, and not at the 2nd position. That way you can chain method and operation calls easily.

Examples

Simple stuff I came with just minutes ago...

(def foo (object {:name "Mr. Foo", :age 20}))
(foo :$get :name)

(foo :throw-fancy-exception!) ;; Calling unknown method causes exceptions to be thrown.
	
(->1 foo
     (:$set :age 30)
     (:$get :age))

(->1 foo
     (:$learn :->string (fn [self] (str (self :$get :name) " " (self :$get :age))))
     :->string)

(->1 foo
     (:$learn :->map (fn [self]
                       (let [attrs (self :$attrs)]
                         (apply hash-map
                                (interleave attrs
                                            (map (partial self :$get)
                                                 attrs))))))
     :->map)

License

Copyright © 2013 Eduardo Julián [email protected]

Distributed under the Eclipse Public License, the same as Clojure.

About

A prototype-like object system based entirely on functions.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published