Lazy List cons

32 views
Skip to first unread message

jogo

unread,
Jun 9, 2011, 10:17:20 AM6/9/11
to Programming Nu
Hi,
can someone explain me this result and give a hint how to fix it?

(macro lazy (*body)
`(let ((__forced nil)
(__value nil))
(do ()
(unless __forced
(set __value (progn ,@*body))
(set __forced t))
__value)))

(macro force (lazy-value)
`(apply ,lazy-value))


% (cons (lazy + 1 2) (lazy (+ 1 2)))
(<NuBlock: 0x1001801f0> . 3)

I expected it to have two NuBlocks. It looks like cons is kind of
forcing the second parameter. Is this intended?

Jeff Buck

unread,
Jun 13, 2011, 2:52:37 AM6/13/11
to Programming Nu
That's not intended. Looks like a bug.

(list (lazy (+ 1 2)) (lazy (+ 1 2))) seems to work okay:

% (set l (list (lazy (+ 1 2)) (lazy (+ 1 2))))
(<NuBlock: 0x100120140> <NuBlock: 0x1001235f0>)
%
% (force (car l))
3
% (force (cdr l))
3

Could you get away with using list instead of cons in the interim?

Jeff

jogo

unread,
Jun 13, 2011, 5:09:38 PM6/13/11
to Programming Nu
I am using it to create infinite lists, so list itself probably wont
work. Anyway it is just for fun porting some examples from Land of
Lisp to Nu.
I fixed it with this:
(macro consl (a d)
`(cons ,a (lazy ,d)))

Heiko Henrich

unread,
May 5, 2012, 6:37:17 AM5/5/12
to program...@googlegroups.com
Found the bug.

Nu cons evaled the cddr as second argument,
it should be the caddr.

This did no harm in most other operations,
but with NuBlocks is is a difference whether you 
have (do () ("x")) or ((do () ("x")) .
So (cons (do () ("x")) (do () ("y"))) yielded (<NuBlock: 0x7fbad2e62dc0> . "y")
But it should: (<NuBlock: 0x7fbad2e62dc0> . <NuBlock: 0x7fbad2e94200>) as jogo expected.
Maybe there was also a deeper sense in the code Tim wrote,
and I am wrong.

So I propose a fix is below, I hope this will work in all situations and not unintentionally break other things.
(I mean cons is one of the basic functions at all)
So maybe a lot of people can test this and tell, wether it works with their things.
So far it seems good for me.


@implementation Nu_cons_operator

- (id) callWithArguments:(id)cdr context:(NSMutableDictionary *)context

{

    id cadr = [cdr car];

    id caddr = [[cdr cdr] car];

    id value1 = [cadr evalWithContext:context];

    id value2 = [caddr evalWithContext:context];

    id newCell = [[[NuCell alloc] init] autorelease];

    [newCell setCar:value1];

    [newCell setCdr:value2];

    return newCell;

}

@end


(BTW, poting code with Google Groups is no fun)

Reply all
Reply to author
Forward
0 new messages