FOOP colon method invocation from string

Q&A's, tips, howto's
Locked
refrainrence
Posts: 10
Joined: Thu Aug 08, 2013 10:03 pm

FOOP colon method invocation from string

Post by refrainrence »

Hi there,

i play with newLISP from time to time because writing code in 'real world' languages feels like merry go round. So to avoid a lapse of reason i'm playing atm with my imaginary programming task which goes :

Take list of method names stored in list of strings ( or symbols - i'm an ignorant noob) and invoke them on an object.

What i have now:

Code: Select all

(define (Circle:area)
    (mul (pow (self 3) 2) (acos 0) 2))

(set 'method1 '(:area))

(set 'mycircle (Circle 1 2 10))

((nth 0 method1)(nth 1 method1) mycircle)

This is my first post, so it's a good time to thank you people, who are behind newLISP for this outstanding piece of software :-)

I'd like to follow with a few more questions considering FOOP in this same thread if you don't mind. The context of newLISP is main reason for using this language to me, so forgive me i started learning from this point and not the basics. I just can't figure out if context from newLISP works for me or not. I'm trying to build my own approach to OOP paradigm. Based on composition, without inheritance. I want to replace PHP with NewLISP as a foundament.

cheers
Last edited by refrainrence on Fri Aug 09, 2013 1:58 pm, edited 1 time in total.

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Re: FOOP colon method invocation from string

Post by cormullion »

Take a look at ObjectiveNewLISP http://www.taoeffect.com/blog/2009/12/i ... e-newlisp/ as well.

hilti
Posts: 140
Joined: Sun Apr 19, 2009 10:09 pm
Location: Hannover, Germany
Contact:

Re: FOOP colon method invocation from string

Post by hilti »

Welcome to the powerful world of newLISP :-)
--()o Dragonfly web framework for newLISP
http://dragonfly.apptruck.de

refrainrence
Posts: 10
Joined: Thu Aug 08, 2013 10:03 pm

Re: FOOP colon method invocation from string

Post by refrainrence »

Thanks hilti, thanks cormullion for objective-newlisp link, i think i may need circular links and deep nested access. I will try to write some lines using objective-newlisp later. But before that, i'm going to do some FOOP scripting.

I managed to write a possible solution:

Code: Select all


(define (Circle:Circle x y radius)
    (list Circle x y radius))

(define (Circle:area)
    (mul (pow (self 3) 2) (acos 0) 2))


(set 'methods '((:area) (:area)))

(set 'mycircle (Circle 1 2 10))

(dolist (x methods) (println "looping: " (eval (append x '(mycircle)))))

output:

Code: Select all

(lambda (x y radius) (list Circle x y radius))
(lambda () (mul (pow (self 3) 2) (acos 0) 2))
((: area) (: area))
(Circle 1 2 10)
looping: 314.1592654
looping: 314.1592654
314.1592654
Does it look alright?

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Re: FOOP colon method invocation from string

Post by cormullion »

Looks good. There are many ways to do it.

Code: Select all

(define (Circle:Circle (x 10) (y 10) (radius 3))
    (list Circle x y radius))
    
(define (Circle:area)
    (mul (pow (self 3) 2) (acos 0) 2))
    
(define (Circle:center)
    (list (self 1) (self 2)))

(define (Circle:circumference)
    (mul 2 (self 3) (acos 0)))

(set 'mycircle (Circle 150 130 170))

(set 'functions '(area center circumference))

(dolist (func functions)
   (println (eval (list ': func mycircle))))
giving:

Code: Select all

90792.02769
(150 130)
534.0707511
But hopefully other more experienced FOOPers can join in...:)

rickyboy
Posts: 607
Joined: Fri Apr 08, 2005 7:13 pm
Location: Front Royal, Virginia

Re: FOOP colon method invocation from string

Post by rickyboy »

I'm not a FOOPer, but I'd like to throw out a few comments for discussion, but be warned that what I'm going to cover does NOT improve essentially on what cormullion just wrote -- it just complements it.

Here's the setup, which is slightly different but essentially the same as yours, refrainrence.

Code: Select all

(define (Class:Class) (cons (context) (args)))
(define pi (mul 2 (acos 0)))

(new Class 'Circle)
(define (Circle:radius) (self 3))
(define (Circle:circumference) (mul 2 pi (Circle:radius)))
(define (Circle:area) (mul pi (pow (Circle:radius) 2)))
(Notice that I defined a method, radius, which is just an accessor. It makes some of the other code easier to read.)

If you want to call a bunch of functions (methods, in this case) on an object, but do it in the functional way (warning: FP is a minority cult on the newLISP forum :), you would call a higher-order function, like juxt. Here is a discussion on it, but basically it is defined like this:

Code: Select all

(define (juxt)
  (letex (_funcs (args))
    (lambda (x)
      (map (lambda (f) (f x)) '_funcs))))
and used like this:

Code: Select all

(define (mulby3 x) (mul x 3))
(define (divby3 x) (div x 3))

((juxt mulby3 divby3) 9)
;; => (27 3)
But juxt will fail miserably, when you use it for your Circle example. For instance, none of these calls work:

Code: Select all

((juxt :radius :area :circumference) mycircle)
((juxt radius area circumference) mycircle)
((juxt Circle:radius Circle:area Circle:circumference) mycircle)
They don't work because methods are invoked differently from regular functions. The colon operator does the dispatching work for you behind the scenes. So if you want to use something like juxt, you'd only need to write a version of it that handles these methods. Here is a version I wrote, and I just called it by a different name juxtm.

Code: Select all

(define-macro (juxtm)
  (letex (_meths (args))
    (lambda (obj)
      (letex (_calls
              (map (lambda (m) (list ': m obj)) '_meths))
        (map eval '_calls)))))
(Notice the eval in there, just as in cormullion's loop.)

Now, it works as expected.

Code: Select all

(setf mycircle (Circle 1 2 10))
(:radius mycircle)
(:area mycircle)
(:circumference mycircle)
((juxtm radius area circumference) mycircle)
yields

Code: Select all

> (Circle 1 2 10)
> 10
> 314.1592654
> 62.83185307
> (10 314.1592654 62.83185307)
Last edited by rickyboy on Fri Aug 09, 2013 6:45 pm, edited 1 time in total.
(λx. x x) (λx. x x)

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Re: FOOP colon method invocation from string

Post by cormullion »

Good work, FOOperman. And thanks for the "compliment"! :)

rickyboy
Posts: 607
Joined: Fri Apr 08, 2005 7:13 pm
Location: Front Royal, Virginia

Re: FOOP colon method invocation from string

Post by rickyboy »

Heck, you figured it out, cormullion. Setting up the calls as data and pushing them through eval was the heart of the matter. Is there a better way? Idk.

I ain't on FOOPer. I really am not into OOP at all. And if I ever did get into FOOP, there are a lot of questions I'd need to answer, the most important of which is what is the inheritance scheme (and I assume the colon operator does the dispatching of methods for you based on the scheme -- but I'm not sure)?

And don't tell anybody that you can make juxtm faster by basing it off of dolist (like you did) as opposed to map. Shhhhh! It will just be our secret. :)
(λx. x x) (λx. x x)

rickyboy
Posts: 607
Joined: Fri Apr 08, 2005 7:13 pm
Location: Front Royal, Virginia

Re: FOOP colon method invocation from string

Post by rickyboy »

cormullion wrote:Good work, FOOperman. And thanks for the "compliment"! :)
Damn you. I just corrected it. Thanks. :)
(λx. x x) (λx. x x)

Locked