Insteresting challenge for us!

Started by ale870, August 13, 2009, 03:07:20 AM

Previous topic - Next topic

ale870

Hello,

I'm a newLisp fan, but I even like Java language, so I always check new features, improvements, planned features, etc...

Today I found "lambdaJ", a java library to implement, in java, some features of functional languages...



Well, this is my challenge proposal:

Look at LambaJ home page: http://code.google.com/p/lambdaj/">//http://code.google.com/p/lambdaj/



There are some examples about this library. They show how easily can be implemented some jobs using it. For a java developer it seems really interesting.

Well, I want to rewrite those examples in newLisp, but they must be:



1) Light and clear. Our newLisp language must implement the proposed algorithms better (code more readable ) than the one implemented in java.



2) newLisp code must be basically equivalent to java code (as length) or even shorter.



My final target is demonstrating that a real functional language like newLisp is better than any "simulation" built inside an imperative one!!!  :-)

I'm joking, but I think this is a good test to compare an imperative languaqe implementing some functional-like features, and a real functional language.

What's newLisp limitations? And java limitations?

Is the final code more clear and readable? Is it shorter? Is it faster? etc...
--

cormullion

#1
I think it would be possible to provide some equivalent newLISP idioms for the ones listed there... It would be interesting to see a FOOP version of some of those object-style code.



I got this far with one of them, but ran out of time.



Edit: another five spare minutes, so I tried to finish:


;lambdaj
;Person me = new Person("Mario", "Fusco", 35);
;Person luca = new Person("Luca", "Marrocco", 29);
;Person biagio = new Person("Biagio", "Beatrice", 39);
;Person celestino = new Person("Celestino", "Bellone", 29);
;List<Person> meAndMyFriends = asList(me, luca, biagio, celestino);
;it is possible to filter the ones having more than 30 years applying the following filter:
;LList<Person> oldFriends = filter(having(on(Person.class).getAge(), greaterThan(30)), meAndMyFriends)
;int totalAge = sum(meAndMyFriends, on(Person.class).getAge());


; newlisp

(new Class 'Person)
(new Class 'Firstname)
(new Class 'Lastname)
(new Class 'Age)

(set 'me  
  (Person
    (Firstname "Mario")
    (Lastname "Fusco")
    (Age 35)))

(set 'luca
  (Person
    (Firstname "Luca")
    (Lastname "Marrocco")
    (Age 29)))

(set 'biagio
  (Person
    (Firstname "Biagio")
    (Lastname "Beatrice")
    (Age 39)))

(set 'celestino
  (Person
    (Firstname "Celestino")
    (Lastname "Bellone")
    (Age 29)))
   
(set 'me-and-my-friends
  (list me luca biagio celestino))

(lookup Age luca)
;-> 29

(map (curry assoc Age) me-and-my-friends)
;-> ((Age 35) (Age 29) (Age 39) (Age 29))

(set 'oldfriends
 (filter (fn (person) (> (lookup Age person) 30)) me-and-my-friends)
;->  
   ((Person  
      (Firstname "Mario")  
      (Lastname "Fusco")  
      (Age 35))  
    (Person  
      (Firstname "Biagio")  
      (Lastname "Beatrice")  
      (Age 39)))

(set 'total-age (apply add (map (curry lookup Age) me-and-my-friends))))

;-> 132



Obvious comparisons: the newLISP is slightly more readable, but more "spacious". I don't think the syntax of the newLISP 'oldfriends' and 'total-age' assignments are more obscure than the lambdaj, but I'm more used to the idioms of the former. I'd agree that neither newLISP example is trivial, perhaps - but not too hard, either.



The talk about hamcrest matchers and idempotent aggregation on the Lambdaj  pages reminds me that I like newLISP for its simplicity and - usually - the absence of Computer Science speak.  But I'm a practical person!

ale870

#2
I think FOOP fits very well for the comparison!
--

cormullion

#3
Some more idioms for this application, continued from previous post:


(define (Person:age self)
    (assoc 'Age self))
   
(define (Person:name self)
    (assoc 'Firstname  self))
   
(define (Person:fullname self)
    (cons (lookup Firstname self) (lookup Lastname self)))
   
(:age luca)
;-> (Age 29)

(:name me)
;-> (Firstname "Mario")

(:fullname me)
;-> ("Mario" "Fusco")

(map (curry : fullname) oldfriends)
;-> (("Mario" "Fusco") ("Biagio" "Beatrice"))

(map (curry : age) oldfriends)
;-> ((Age 35) (Age 39))

; this is a more 'live' version of oldfriends

(define (Person:oldfriends)
   (filter (fn (person) (> (lookup Age person) 30)) me-and-my-friends))

; change all 'old' friend's ages to have the value 30
(set-ref-all '(Age ?) oldfriends (if (> (last $0) 30) '(Age 30) $0) match))