Arc Forumnew | comments | leaders | submitlogin
More Jarc and Rainbow bugs
2 points by rocketnia 5147 days ago | 9 comments
My previous thread fell off the front page, so here's a new one. ^_^ I only have one new bug to report right now, which is that on both platforms, optional arguments don't work very well inside of destructuring arguments.

Official Arc 3.1:

  Use (quit) to quit, (tl) to return here after an interrupt.
  arc> (let ((o x 2)) nil x)
  2
  arc> (let (a (o b 2)) '(1) b)
  2
  arc> (let default 2 ((fn ((o x default)) x)))
  2
  arc> (let default 2 (let ((o x default)) nil x))
  2
  arc> (let default 2 (let (a (o b default)) '(1) b))
  2
  arc>
Jarc 19:

  Jarc> (let ((o x 2)) nil x)
  (stdin):1: Error: Type-error:
    (o x 2) is not of type SYMBOL
  
  0:      ((fn (((o x 2))) x) nil)
  DEBUG 0: q
  
  Jarc> (let (a (o b 2)) '(1) b)
  (stdin):3: Error: Insufficient DS arguments, missing value for (o b 2)
  
  0:      ((fn ((a (o b 2))) b) (quote (1)))
  DEBUG 0: q
  
  Jarc> (let default 2 ((fn ((o x default)) x)))
  2
  Jarc> (let default 2 (let ((o x default)) nil x))
  (stdin):6: Error: Type-error:
    (o x default) is not of type SYMBOL
  
  0:      ((fn (((o x default))) x) nil)
  DEBUG 0: q
  
  Jarc> (let default 2 (let (a (o b default)) '(1) b))
  (stdin):8: Error: Insufficient DS arguments, missing value for (o b default)
  
  0:      ((fn ((a (o b default))) b) (quote (1)))
  DEBUG 0: q
  
  Jarc>
Rainbow:

  *** redefining no
  *** redefining map1
  *** redefining pr
  *** redefining list
  repl in 8688ms
  arc> (let ((o x 2)) nil x)
  2
  arc> (let (a (o b 2)) '(1) b)
  2
  arc> (let default 2 ((fn ((o x default)) x)))
  2
  arc> (let default 2 (let ((o x default)) nil x))
  Exception in thread "main" java.lang.IllegalArgumentException: Illegal Capacity: -1
          at java.util.ArrayList.<init>(ArrayList.java:110)
          at rainbow.vm.VM.handleError(VM.java:135)
          at rainbow.vm.VM.loop(VM.java:95)
          at rainbow.vm.VM.thread(VM.java:58)
          at rainbow.Console.compileAndEval(Console.java:193)
          at rainbow.Console.interpret(Console.java:127)
          at rainbow.Console.repl(Console.java:117)
          at rainbow.Console.main(Console.java:59)
  Press any key to continue . . .
The last line there is my cue that the batch process is ending and I'm going to lose the command window. The same error occurs if I enter (let default 2 (let (a (o b default)) '(1) b)).


4 points by suzuki 5146 days ago | link

My Semi-Arc 10.1 looks perfect;)

  $ java -jar semi_arc.jar 
  arc> (let ((o x 2)) nil x)
  2
  arc> (let (a (o b 2)) '(1) b)
  2
  arc> (let default 2 ((fn ((o x default)) x)))
  2
  arc> (let default 2 (let ((o x default)) nil x))
  2
  arc> (let default 2 (let (a (o b default)) '(1) b))
  2
  arc> (let (x y) '(a b c) y)
  *** 2 args expected for #<fn:2::(#((a b c)))>: (a b c)
    0: (#<done> #<fn:2::(#((a b c)))> a b c)
  arc> (let (x y z nothing) '(a b c) nothing)
  *** 4 args expected for #<fn:4::(#((a b c)))>: (a b c)
    0: (#<done> #<fn:4::(#((a b c)))> a b c)
  arc>

-----

2 points by rocketnia 5145 days ago | link

I upvoted you 'cause Semi-Arc's doing what you want it to do (which is what really matters), but I'd like to mention that I actually kinda appreciate the way Arc accepts mismatched destructuring lengths.

I've seen other people's code use a (let (a b c) nil ...) idiom as a shortcut for (with (a nil b nil c nil) ...). As for me, I like being able to design multiple types so that they can be used in an ad-hoc polymorphic way like this:

  arc>
    (def theta (point)
      (let (x y) rep.point
        (errsafe:atan y x)))
  #<procedure: theta>
  arc>
    (let point (annotate 'point3d
                 '(-1 0 200))
      theta.point)
  3.141592653589793
Both these techniques could still be used in an Arc implementation with a stricter treatment of destructuring: The first could be done by defining a 'w/nil macro, and the second could be expressed as (let (x y . rest) rep.point ...). In your favor, the strict treatment makes it easier to write functions that do complain if the length is incorrect, encouraging fail-fast code. However, as far as portability is concerned, the "N args expected" errors are a quirk of Semi-Arc.

I'm going to try out Semi-Arc right now. ^_^ I'm sure I'll have some error reports for you in a moment. Hopefully not too many! :-p

-----

1 point by akkartik 5146 days ago | link

Nice. Have you played around with multiple arc implementations in the process of making semi-arc? I'd love to read about your experience writing semi-arc, and the design decisions you made. (email in profile if you want to chat further)

-----

4 points by suzuki 5145 days ago | link

No, I have not played the original Arc yet and had hardly known both implementations in Java until recently. My version 1 implementation was a little Lisp written in ISO Standard Pascal:

  Little Lambda Lisp in Standard Pascal
  http://www.oki-osk.jp/esc/llsp/v1.html
You find the notable(?) feature of Semi-Arc, macro expansion without free symbol capture, even in the version 2 of it:

  Little Lambda Lisp 2 in Standard Pascal
  http://www.oki-osk.jp/esc/llsp/v2.html
I had translated it to Ruby, Python, C# and Java. Recently I noticed that its design is near to the core of Arc. I made it up so that it may look Arc:-). The result is Semi-Arc.

As for argument destructuring, I implemented it in a simple, general and recursive (but not so efficient) way. Track the variable 'nestedArgs' in the method 'compile(Cell j, Cell env)' in the source:

  Interp.java
  http://www.oki-osk.jp/esc/llsp/10/1/Interp.java.html
Also, you can inspect the implementation interactively:

  arc> (def f ((a b)) (+ a b))
  #<fn:1>
  arc> (inspect f)
  (#<fn> ((1)) (apply (#<fn> ((2) #<none>) (+ #0:0:a #0:1:b)) #0:0:$G453))
  arc>

-----

2 points by conanite 5146 days ago | link

Quick note on destructuring behaviour: arc3 doesn't verify parameter counts in destructuring arg lists.

You can see this in the wild in 'parseurl in srv.arc:

  (let (type url) (tokens s) ...)
(tokens s) returns a 3-element list (it's tokenising "GET /foo HTTP/1.1").

Here are two examples destructuring a 3-element list into a 2-element arg, and into a 4-element arg:

  arc> (let (x y) '(a b c) y)
  b ; no error
  arc> (let (x y z nothing) '(a b c) nothing)
  nil ; no error

-----

2 points by conanite 5147 days ago | link

Thank you. The bit that compiles argument lists wasn't recursing down destructuring arguments to check for optional arguments there. Fix pushed to github this morning :)

-----

1 point by rocketnia 5147 days ago | link

Very nice, thanks! ^_^

-----

1 point by rocketnia 5147 days ago | link

For reference, the previous thread is at http://arclanguage.org/item?id=12269.

-----

1 point by jazzdev 5118 days ago | link

I've fixed these Jarc bugs in Jarc 21. I would not have thought to try nesting optional args inside destructuring. Should work, though, of course. And actually the Jarc code is cleaner this way.

-----