Arc Forumnew | comments | leaders | submitlogin
2 points by akkartik 3668 days ago | link | parent

Hmm, I think you need to do more to redefine scar and scdr:

  arc> (= x '(1 2 3))
  arc> x
  (1 2 3)
  arc> (= car.x 4)
  4
  arc> x
  (4 2 3)
  arc> (load "lib/streams.arc")
  *** redefining scar
  *** redefining scdr
  nil
  arc> (= car.x 5)
   scar: arity mismatch;
   the expected number of arguments does not match the given number
    expected: 1
    given: 2
    arguments...:
     '(4 2 3 . nil)
     5
The problem is that prior uses of scar and scdr (such as assignment to car[1]) will try to call your version. It's usually a bad idea to repurpose names for something unrelated. At the least we need to go through and fix callers of the old name.

Not a huge deal at the moment since your library isn't loaded by default. So we have some time to think about how to fix this.

[1] https://github.com/arclanguage/anarki/blob/3662afea89/arc.ar...



2 points by malisper 3668 days ago | link

The simplest fix would be to overload scar/scdr based on the number of arguments. While it's a nice quick fix, I do not like the idea of using the same name for two different functions.

-----

1 point by akkartik 3668 days ago | link

Yeah, especially since one of them is destructive and one isn't!

If we can get regular car and cdr to handle lazy streams then this issue will be moot. I'm investigating this. I didn't understand your point 1 above regarding when to tag, so I'm trying to recreate the primes example from SICP 3.5 to better understand the issue.

Can you point me at any sample calls to your library, maybe things you tried on the commandline while you built it?

-----

2 points by rocketnia 3668 days ago | link

Now may be a good time to mention almkglor's lazy list library for Arc 2, which did extend 'car and 'cdr like you're talking about:

https://github.com/arclanguage/anarki/blob/arc2.master/lib/s...

---

Meanwhile, here's a generator library for Arc 2 by rkts: https://github.com/arclanguage/anarki/blob/arc2.master/lib/i...

And here are three relevant libraries I made as part of Lathe:

- A lazy list library, which happens to use a multimethod framework I made: https://github.com/rocketnia/lathe/blob/master/arc/orc/oiter...

- A generator library: https://github.com/rocketnia/lathe/blob/master/arc/iter.arc

- An amb operator library: https://github.com/rocketnia/lathe/blob/master/arc/amb.arc

I've never actually found much use for these, heh.

-----

1 point by akkartik 3668 days ago | link

Thanks for the links! Too bad none of them show example usage.. :) But no matter, I'll add some to this version. It's looking promising so far, I'll push it later today.

One thing I learned from malisper's code was the existence of afnwith in anarki (https://github.com/arclanguage/anarki/blob/87d986446b/lib/ut...), which is a neat alternative solution to my http://arclanguage.org/item?id=18036.

-----

1 point by akkartik 3668 days ago | link

Ok, I've turned streams into a tagged type. I had to just support them in car and cdr and carif to get common list operations to work. However, existing operations still return regular (eager) lists when you pass them lazy streams, so I followed malisper's idea of creating lazy variants that preserve laziness in the result.

I've also added unit tests for them in lib/streams.arc.t, which is my first serious attempt at using zck's nice unit-test harness with suites.

malisper, I took some liberties with your code, such as renaming the 's' prefix to 'lazy-'. I'm not attached to these things, so feel free to revert any of my changes you don't like. Thanks for a fun exercise!

I'm not sure how you're measuring overhead, but let me know if it seems slower than before.

https://github.com/arclanguage/anarki/commit/6180f0e65

-----

2 points by malisper 3667 days ago | link

Why append lazy to the beginning when we can just extend all of them to use scons when given a stream.

-----

1 point by akkartik 3667 days ago | link

Well, you need it for cons and the generator lazy-gen and other functions that don't take a stream. Maybe the others don't, but it seemed to me that sometimes it makes sense to return a list and sometimes not. So especially since functions like firstn do something useful without changing anything, maybe we should keep that behavior around. But it's just an idea. What do you think? Since you're using them for project Euler, it'll be good to hear your experiences.

-----

2 points by rocketnia 3668 days ago | link

I'm a little surprised to see 'afnwith. Anarki also has aw's 'xloop, which is the exact same thing as 'afnwith but with the "self" anaphoric variable renamed to "next".

-----

1 point by akkartik 3668 days ago | link

Ah, that's a much nicer name. I (too) found the presence of fn to be misleading since the afn is called immediately after it's created.

I've deleted afnwith from anarki: https://github.com/arclanguage/anarki/commit/a0052f031

In wart the name can be nicer still -- just loop since for does what arc's loop does, in the footsteps of classical C.

Edit 20 minutes later: I ended up going with recur instead of next, to form a loop.. recur pair. I also considered with loop.. recur to strengthen the connection with with for the alternating var/val syntax. (The other pair of keywords in wart is collect.. yield in place of accum acc.) https://github.com/akkartik/wart/commit/b7b822f4fb has has an example use, which had me hankering for absz's w/afn (though with a better name; http://arclanguage.org/item?id=10125)

Edit 25 minutes later: It turns out xloop nests surprisingly cleanly. This does what you expect:

  loop (a 0)
    loop (b 0)
      prn a " " b
      if (b < 5) (recur ++b)
    if (a < 5) (recur ++a)
Edit 29 minutes later: Oh, loop.. recur is precisely what clojure uses!

-----

3 points by shader 3659 days ago | link

I feel like we need to extend the documentation on arclanguage.github.io to include the extra libraries on anarki, to improve discoverability.

-----

2 points by malisper 3668 days ago | link

I don't know what I was thinking. Of couse we could just tag the streams when they are created with scons. If we really wanted to we could just extend all of the basic operations for working with lists.

There still is the problem of efficiency though. For what I have been using them for (project euler) efficiency is a big deal.

-----