Other ways to pass variable by reference

Started by Fritz, January 28, 2010, 11:11:08 AM

Previous topic - Next topic

Fritz

I`m trying to find some easy way to cut lists to the limited size.


(0 100 '("Some" "long" "list")) returns me first 100 dwellers of the list.



(By the way, expression (-100 100 '("Some" "long" "list")) says: "ERR: list index out of bounds" if the list is not long enough. But same expression works ok with strings).



Then I have tried to create a function, that will push an item to the list and cut it to the size I need.


(define (push-cut what where how-long)
  (push what where)
  (if (> (length where) how-long)
    (set 'where (0 how-long where)))
  0)


And... it won`t work. I have found some method in "Code Patterns": make a context and transfer variables like db:db.



But I`m pretty sure, there should be some other way to expain to the function, which variable I want to be pushed.

Kazimir Majorinc

#1
Your error is that you assume that, if you call



(push-cut 7 L 3)




L and variable where can have *same* value. They cannot. It is ORO, one reference only. So, where is the solution? You must pass original reference, L, to the function, so function will "work" with original reference.


(define (push-cut what where how-long)
  (push what (eval where))
  (if (> (length (eval where)) how-long)
      (set where (0 how-long (eval where)))
     0))
 
(set 'L '(1 2 3 4))
(push-cut 7 'L 3)
(println L) ;(7 1 2)


If you do not like that apostrophe in (push-cut 7 'L 3) you can use macro


(define-macro (push-cut what where how-long)
  (push (eval what) (eval where))
  (if (> (length (eval where)) (eval how-long))
      (set (eval 'where) (0 (eval how-long) (eval where)))
      0))

(set 'L '(1 2 3 4))
(push-cut (+ 1 6) L (+ 1 2))
(println L) ;(7 1 2)


 And this is if you want it to work with more general references:


(define-macro (push-cut what where how-long)
  (eval (expand '(begin (push (eval what) where)
                        (if (> (length where (eval how-long)))
                            (setf where (0 (eval how-long) where))
                            0))
                'where)))

(set 'L '(1 2 3 4))
(push-cut (+ 1 6) L (+ 1 2))
(println L) ;(7 1 2)

(set 'L '((1 2 3 4)(3 4 5 6) (5 6 7 8)))
(push-cut 12 (L 1) 2)
(println L) ;((1 2 3 4) (12 3) (5 6 7 8))
(exit)


Heavy use of eval might look strange, but, in my opinion, it is how it should be in Newlisp. If you do not use contexts.
http://kazimirmajorinc.com/\">WWW site; http://kazimirmajorinc.blogspot.com\">blog.

Fritz

#2
Thank you. I`ll try these variants now.