Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - itistoday

#436
I'm trying to create a tree class using http://www.alh.net/newlisp/phpbb/viewtopic.php?p=11096">the data-type macro Lutz introduced.  The class is created like so:


(data-type (tree data children))

data can be anything, and children is a list of other trees.  So say I want to define a function (or macro, don't know which) called tree:add-child that takes a tree node and a child node and adds the child to the parent node's children list.  How do I do this without copying data?  I just want to update the list inside the parent without having to duplicate and replace it.



If the data is an integer, then an example of a node containing 2 leaf nodes is this:


(tree 0 ((tree 1 ()) (tree 2 ())))

Also, I do not want this to be a solution involving creating a context for every object, because I want to be able to refer to these things anonymously and in general that's not a very elegant solution as it requires that you have a naming scheme for your context symbols (like tree1, tree2, etc...).



Any help is much appreciated!
#437
newLISP newS / (length my-list) - O(n) or O(1) ?
December 03, 2007, 07:00:06 PM
Does (length) calculate the size of a list by iterating through its elements or is there a value stored somewhere internally?
#438
Anything else we might add? /
December 03, 2007, 06:29:14 PM
OK, this is getting frustrating, I'm starting to get the impression that newLISP just isn't designed for object oriented programming (edit: which appears to be what Lutz said above, now that I'm reading through this thread in more detail...).  Using my previous code this does not work:


(set 'points '())
(dotimes (i 5)
(push (point i i) points)
)
(println (point:move '(points 0) 200 200))


I'm guessing you've probably gotta jump through some hoops by using temporary variables to get that to work...  Yeah, this works:


(set 'points '())
(dotimes (i 5)
(push (point i i) points)
)
(set 'tmp (points 0))
(println (point:move 'tmp 200 200))
(nth-set (points 0) tmp)


This is slightly disappointing... I'm hoping some newLISP guru will put my newbie-self in place and show me the proper way to do this...



Edit:  I think it's possible to actually get this to work by writing code to anticipate this situation in data-type.  For example it could check (list? _str) and if so then do the temporary variable thing itself.  Anyone wanna give this a shot?  I won't be able to work on this right now because I've got an another project, but once that's done if no one's done it I'll give it a shot and post here if I'm successful.
#439
Anything else we might add? /
December 03, 2007, 06:19:58 PM
OK, I haven't been able to figure out how to get it working using the previous paradigm, but I did fix it by changing the semantics a bit.



The data-type function is the same except the setter/getters are functions instead of macros:


(define-macro (data-type)
(let (ctx (context (args 0 0)))
    (set (default ctx) (expand '(fn () (cons ctx (args))) 'ctx))
    (dolist (item (rest (args 0)))
(set 'idx (+ $idx 1)
(sym item ctx)
(expand '(lambda (_str _val)
(if (set '_val (eval _val))
          (nth-set ((eval _str) idx) _val)
          ((eval _str) idx)
)
)
'idx
)
)
)
ctx
)
)


Next, forget about the macro-like syntax of (point:x pt 5).  Instead, quote the point:


(point:x 'pt 5)

That works.  Now I've even been able to get compound functions (not macros) to work:


(define (point:move _pt _x _y)
(point:x _pt _x)
(point:y _pt _y)
(eval _pt)
)

(point:move 'pt 8 7)


That works too.  And not only that, but using the colon syntax for getting works too! (but *not* setting)

Except you use the previous format of not quoting the object.


(:x pt)

If anyone figures out how to get this working using macros though... let me know.  It seems to me that newLISP macros have something funky going on with them besides simply changing their parameters to be quoted...
#440
Anything else we might add? / IRC channel
December 03, 2007, 05:31:33 PM
Is there an IRC channel for newLISP?  I think it would be really helpful to the entire community if there was...
#441
Anything else we might add? /
December 03, 2007, 05:24:40 PM
Hi, while playing around with Lutz's original macro I tried to do stuff like this:


(:x pt 2)

And it didn't work.  :p



So I set about to fix that.  I had planned on reading this thread when I was finished and low and behold I saw that michael had done a similar thing.  I then copied some of the suggestions made in this thread to make the code even nicer.  However, I'm still having problems, and forgive me but I only skimmed over this thread.



(BTW michael, here are smaller versions of those pictures, just remove the -big from the URL: http://www.kenrockwell.com/bmw/images/m3-2007/top-790.jpg">pic1, http://www.kenrockwell.com/bmw/images/m3-2007/exploded-789.jpg">pic2)



So here is my version as it is now:


(define-macro (data-type)
(let (ctx (context (args 0 0)))
    (set (default ctx) (expand '(fn () (cons ctx (args))) 'ctx))
    (dolist (item (rest (args 0)))
(set 'idx (+ $idx 1)
(sym item ctx)
(expand '(lambda-macro (_str _val)
(if (set '_val (eval _val))
          (nth-set ((eval _str) idx) _val)
          ((eval _str) idx)
)
)
'idx
)
)
)
ctx
)
)


However, (:x pt 5) still doesn't work!  It runs, it just doesn't modify pt. Oddly enough (point:x pt 5) does.  Can anyone help me out here as to why this is happening?



Also, how do I write a compound method like this:


(define-macro (point:move _pt _x _y)
(:x _pt _x)
(:y _pt _y)
)

; this doesn't work either

(define-macro (point:move _pt _x _y)
(point:x _pt _x)
(point:y _pt _y)
)

; if I try this:
(define-macro (point:move _pt _x _y)
(println (point:x _pt))
)

; I get this error:
invalid function : ((eval MAIN:_str) 1)


So that when I do (:move pt 5 6) [or (point:move pt 5 6)], point should contain the values 5 and 6.  Many thanks!
#442
newLISP newS /
December 03, 2007, 03:13:35 PM
Quote from: "cormullion"Sounds like a good idea - for all types to be equal!


You can sort a list that contains mixed-type elements, so I see no reason why you couldn't do the same for an array.  I wrote a C vector implementation a while ago that let you do this, you can use it just like a list, except insertions/removal from anywhere other than the back take longer.   You just have an array of pointers to "DataHolder" unions that can be anything.  It would then follow the same rules that sort uses for lists.
#443
newLISP newS /
December 03, 2007, 01:14:32 PM
Hi, I'm a newLISP newBIE and while trying to understand Lutz's awesome macro I went through and formatted it nicely in C-style and added comments.  If there are any other newbies out there that are confused by it perhaps this may help:


(define-macro (data-type)
(let (ctx (context (args 0 0)))
; sets the constructor
    (set (default ctx) (lambda () (args)))
; create getters and setters
    (dolist (item (rest (args 0)))

(set (sym item ctx) ; creates something like point:x

; the reason expand is used is because we want the
; point:x method to print stuff based on a number,
; not the value of a variable $idx when it's called.
; In other words it's the difference between:
; (print (my-list $idx))
; and
; (print (my-list 5))

(expand '(lambda-macro (_str _val)
(if (set '_val (eval _val))
; if value is specified act as a setter
          (nth-set ((eval _str) $idx) _val)
; otherwise act as a getter
          ((eval _str) $idx)
)
)
; internal var representing current index
; for dolist expression
'$idx
)
)
)
ctx
)
)
#444
newLISP newS / Better array support?
December 02, 2007, 06:44:18 PM
Is this planned for the future?  It would be nice if more of the functions that operated on lists would also operate on arrays, for example (sort).  As a big fan of newLISP I would be glad to help implement this myself, it's just that school won't give me a minute's rest.  :