Arc Forumnew | comments | leaders | submitlogin
2 points by rocketnia 5008 days ago | link | parent | on: Wart update: compose is now '+'

"I assumed you were saying that wart wouldn't be able to include '+' in symbol names, but that was already true before this change."

Ah, point taken! You were already treating + as infix. Got it. ^_^

2 points by akkartik 5008 days ago | link | parent | on: Cyclical data structures in arcueid

You got me rereading R-1RK, and I was reminded again of how much I like the way Shutt connects up his design decisions to design goals and constraints. It's very in the spirit of Christopher Alexander (http://www.amazon.com/Notes-Synthesis-Form-Harvard-Paperback...).

In spite of the level of detail, kernel's design goals diverge so quickly from my own that I can't reuse any of the design work. It's really too bad.

Today's frustrating example: I really couldn't give a rat's ass that Kernel permits cyclical argument lists in operatives but not applicatives. Then in A.4 he talks about what's missing before R0RK, and the support for cycles feels pedantic next to the problem of a fast implementation. If he wasn't so concerned about handling cycles during eval perhaps the code wouldn't be slow. How the heck can a language be slower than wart?!

2 points by akkartik 5008 days ago | link | parent | on: Wart update: compose is now '+'

:) I assumed you were saying that wart wouldn't be able to include '+' in symbol names, but that was already true before this change. Wart has other constraints, but if you can use '&' for something you can also use '+'.

Does that trigger memories? Did I understand you right? Were you nostalgic for the good old days when wart symbols could include '+'? ^_^

1 point by akkartik 5008 days ago | link | parent | on: Cyclical data structures in arcueid

I'm flattered that you remember wart's nils :) And why would you imagine I care about compatibility?! Oh, you mean dido.

It's a good question whether you ever need cycles outside of these two scenarios. Hmm..

2 points by Pauan 5008 days ago | link | parent | on: Cyclical data structures in arcueid

My solution to this (while breaking compatibility with Arc) is to just not have mutable cons cells. I only see two legitimate uses for mutable cons cells:

1) Speed. But honestly, if you're micro-optimizing your Arc code by mutating conses...

2) Intentionally infinite lists, like akkartik's "nils":

  (= nils (list nil))
  (= cdr.nils nils)
I'm not concerned about the first case, especially because a sufficiently smart compiler should be able to handle immutable cons cells reasonably (I believe Racket does).

As for the second case... I think that's solved by adding in a more general system for dynamically generating lazy lists. Then akkartik's "nils" can be written like this:

  (= nils
    ((afn ()
       (lazy-cons (fn () nil)
                  (fn () (self))))))
Basically, lazy-cons takes two thunks: the first is called to extract the car, and the second to extract the cdr. This lets you dynamically create all kinds of nice things, like streams, and it isn't limited to constant values like cyclic lists are.

Thus, you get all the benefits of immutable conses and a strictly more powerful system for lazy list generation. The only possible downside is some performance, which I don't think would be a big deal.

Of course, I already know you're going for full Arc compatibility, so this post is probably useless, but oh well.

1 point by akkartik 5008 days ago | link | parent | on: Cyclical data structures in arcueid

Yes, the print example was just an illustration. It was also a good test for wart; I caught several bugs :) https://github.com/akkartik/wart/compare/686828edba...0e2388.... The tests are pretty self-contained.

I'd assumed I could apply Floyd's hare to handle cars as well, but you're right, now I'm not so sure. The key difficulty is that there's two dimensions, so does the number of hares double each iteration?

Here's a flat-cycle-detecting iso I've been playing with:

  def (iso a b)
    ((afn ((a harea|through) (b hareb|through))
      (if ~list?.a
            (a = b)
          (addr.a = addr.harea)
            (addr.b = addr.hareb)
          :else
            (and (iso car.a car.b)   # Can't detect cycles through car.
                 (self `(,cdr.a :through ,cdr+cdr.harea)
                       `(,cdr.b :through ,cdr+cdr.hareb)))))
      (list a :through cdr.a)
      (list b :through cdr.b))
2 points by rocketnia 5008 days ago | link | parent | on: Wart update: compose is now '+'

I don't know what my point was in posting that link--I mulled over it for a long time before just posting what I'd typed in--and now I don't understand your reply. What did you take off the table, and when? ^_^;
2 points by rocketnia 5008 days ago | link | parent | on: Cyclical data structures in arcueid

Both of the things you're talking about look specialized for cycles in flat lists. I think dido's examples could have just as easily used 'scar instead of 'scdr.

  arc> (= x '(1 2))
  arc> (scar x x)
  ((...) . 2)
  #0=(#0# . 2)
I do like the (1 2 ... (3 4 ...)) notation for cyclic lists though. :)

The Kernel R-1RK has a good approach to treating flat cyclic lists as though they're a usual case. IMO, it means everything that deals with lists is more complicated to explain and arguably doesn't even deal with "lists."

2 points by akkartik 5009 days ago | link | parent | on: Cyclical data structures in arcueid

Hi dido, I have 2 comments:

1. Using a hash table for cycle detection can get prohibitive for large cycles. Fortunately there's Floyd's algorithm which detects cycles without the space overhead: https://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_h.... Here's how you might print an infinite list, one item to a line:

  -- z.wart
  def (print x hare)
    if ~list?.x
         prn x
       (addr.x = addr.hare)  # like arc's is
         prn '...
       (do (prn car.x)
           (print cdr.x (cdr+cdr (or hare x))))  # + is compose

  # create a cycle
  (<- x  '(1 2)
      lastcdr.x  x)

  prn (firstn 5 x)
  print x
To run it:

  $ git clone http://github.com/akkartik/wart
  $ cd wart
  $ git checkout f171a9d878    # Unnecessary except for visitors in the far future
  $ ./wart
  ready! type in an expression, then hit enter twice. ctrl-d exits.
  load "z.wart"
  (1 2 1 2 1)
  1
  2
  ...
2. You mentioned a couple of possible notations for cycles in lists. Here's my suggestion:

  (1 2 ...)    # means (1 2 1 2 ..)
This works especially well because wart uses ... for dotted lists:

  (1 ... 2)   # read as '1 consed with 2'
  (1 2 ...)   # read as '1 2 consed with itself'
Finally, you could represent more complex cycles as well:

  (1 2 ... (3 4 ...))    # (1 2 3 4 3 4 3 ..)
1 point by akkartik 5009 days ago | link | parent | on: Wart update: compose is now '+'

..which I've already taken off the table :)
2 points by rocketnia 5009 days ago | link | parent | on: Wart update: compose is now '+'

Here's a discussion I remember every time I think of whether or not to use + as an identifier character: http://arclanguage.org/item?id=10069 "Looks like the answer is to use & instead of +. I like the look of + better, but I can tell people are going to want to use it in names."
2 points by akkartik 5010 days ago | link | parent | on: Number - Real

Update: I just realized my print solution sucks:

  arc> (prn (/ 3 2))
  1.5
  arc> (prn (list (/ 3 2)))
  (3/2)
Rolling it back. Let's just explicitly use real for now.
2 points by jsgrahamus 5010 days ago | link | parent | on: Number - Real

I like the (real (/ 3 2)) format. You easily get both.
2 points by akkartik 5010 days ago | link | parent | on: Number - Real

Yeah, I don't actually want to see rationals at the prompt. It's just that lisp has this nice distinction between 'write and 'print, with the guarantee that 'read can handle anything 'write emits. I'm loath to have write+read change a value in subtle ways.

In this case, that the repl uses 'write is an unfortunate constraint. Still thinking..

1 point by Pauan 5011 days ago | link | parent | on: Number - Real

Well, the whole reason I did it in Arc/Nu was because I liked to use the REPL as a calculator, and I hated having it print rationals. So, having the REPL print rationals kinda defeats the point in my eyes, but I don't care since I don't use Anarki.
1 point by akkartik 5011 days ago | link | parent | on: Number - Real

Thanks, I ended up going with the third option, but with a twist: display prints inexact but write prints exact. So at the prompt you still see exact numbers:

  arc> (/ 3 2)
  3/2
  arc> (prn "aa: " (/ 3 2))
  aa: 1.5
https://github.com/nex3/arc/commit/a9dc15d701
2 points by akkartik 5011 days ago | link | parent | on: Number - Real

Ok, done. For some reason I thought your trick was more permissive..
1 point by Pauan 5011 days ago | link | parent | on: Number - Real

Since that's being done in Anarki, I'd rather use $.exact->inexact, rather than relying upon Racket's auto-coercion. My trick is best used in Arc 3.1 which doesn't have (easy) access to Racket.
2 points by Pauan 5011 days ago | link | parent | on: Number - Real

"Should exact or inexact be the default subtype for num?"

I see at least a few good solutions:

1) Use floating point everywhere. This is what JavaScript (and Nulan) do. Simpler, but it means you give up exact math on rationals.

2) Use floating point by default but support coercing to exact. This may or may not lose information, I don't know. Alternatively, support exact by default and coerce to floating point.

3) Do things the way Racket does it, but when printing the number, coerce it to floating point. This is what Arc/Nu does:

  > 3/2
  1.5
This has the benefit that math calculations are exact, but the result is printed in a more readable fashion (more readable to me anyways).
2 points by akkartik 5011 days ago | link | parent | on: Number - Real

Hmm, I thought about it some more, and it seems worth preserving exact because you lose information in going to inexact.

The solution I ended up with was to use your name and Pauan's trick: https://github.com/nex3/arc/commit/4227a4a9b9.

Now instead of

  (coerce (/ 3 2) 'num)
You'd say:

  (real (/ 3 2))
What do you think? Easy to change if you prefer.
3 points by jsgrahamus 5011 days ago | link | parent | on: Number - Real

I vote for inexact.
1 point by jsgrahamus 5011 days ago | link | parent | on: Number - Real

Good catch, Pauan. Thanks.
1 point by akkartik 5012 days ago | link | parent | on: Number - Real

Anarki lets you escape down to scheme, so I've been doing just:

  ($.inexact->exact (/ 3 2))
Perhaps it's worth fixing this in coerce? Should exact or inexact be the default subtype for num?
2 points by Pauan 5012 days ago | link | parent | on: Number - Real

Fun fact: in Racket, you can use this:

  (+ (/ 3 2) 0.0)
The same thing works in Arc and it'll be much faster than calling `num`
1 point by jsgrahamus 5012 days ago | link | parent | on: Number - Real

Thanks, zck.

So I can use this:

  (coerce (num (/ 3 2)) 'num) --> 1.5
1 point by zck 5012 days ago | link | parent | on: Number - Real

What did you want the type of the result to be?

If you want a string, for output, you can use `num` (http://files.arcfn.com/doc/string.html#num):

    arc> (num (/ 3 2))
    "1.5"
If you want some sort of floating-point, I suppose you could use `nearest`, which was renamed from `to-nearest` a while ago (http://files.arcfn.com/doc/math.html#to-nearest):

    arc> (nearest (/ 3 2) .1)
    1.5
That still returns a number:

    arc> (type (nearest (/ 3 2) .1))
    num
It's kind of ugly, but I don't know of any better way.
2 points by jwk 5013 days ago | link | parent | on: Any Ideas Why I am Getting 502 Proxy Errors?

Thank you all folks. Will likely do this next weekend and report back!

I just want to add a link on the top bar, like a "news" tab, then the visitor click on that it will turn to http://blog.geek.vn subdomain. Anyways, the previous threat submitted by jwk is so helpful to me.

"I wonder how to add another tab such as blog"

I think you want the earlier thread jwk was referring to: http://www.arclanguage.org/item?id=17139.


"Your ARC code tunrs to 127 :-), not real IP."

That's weird. I just doublechecked, and the fix as in anarki seems to be working.

Are you running behind nginx? I think it requires some tweaks to pass through X-Forwarded-For..

More