Arc Forumnew | comments | leaders | submit | fallintothis's commentslogin

"Oy. This is just one of many implementations of Arc we've experimented with over the past 5 years. Others have been built on top of Common Lisp." - http://reddit.com/r/programming/info/bstl/comments/cbtce

Granted, this was referring to a different Scheme's implementation, but I think the basics hold. Not that it's a specific "why", but it would appear that several different implementations of Arc have been tried and the MzScheme one stuck for reasons being explored in this thread.

-----

4 points by fallintothis 6478 days ago | link | parent | on: acond for Arc

Though, of course, the idea in Arc is to use aif and avoid all those unnecessary parentheses as in cond:

  (= airport (table))
  (= (airport 'yyz) "Toronto")
  (aif (airport 'sfo) (prn "This won't print " it)
       (airport 'yyz) (prn "I'm flying to " it))
On the other hand, it's good that you can easily extend Lisps with virtually any control structure you want. To each their own, so far as the parentheses-laden cond vs. parentheses-lacking if issue goes.

-----

1 point by kostas 6477 days ago | link

I was wondering why acond wasn't included in arc.arc. Now I see why. The Arc aif is definitely better. Thanks.

-----

2 points by fallintothis 6490 days ago | link | parent | on: macro / function question

The problem with multiple values being subsequent accesses is it would also interfere with a useful syntax (not actually in Arc, but I mean insofar as deciding which it should mean), and that's subsequence indexing. It's been discussed all over the place, e.g. http://arclanguage.org/item?id=449

With the assumption that one of them takes that syntax, what should be used for the other? How about (seq '(0 3 ...)) or (seq (0 3 ...))? It would similarly be fitting for any number of arguments, be they dimensions or indices, though I would vouch to use the list for n-dimensional indexing as the case of subsequences seems more common. Plus the use of a list distinguishes the one type of access from the other without having to go (...((seq 0) 3) ...).

Not that any of this helps your problem. Just something I noticed.

-----

2 points by fallintothis 6490 days ago | link | parent | on: Are Arc macros hygienic after all?

Doesn't look like anything should fail to me. Looks like the do inside of the withs call is being expanded:

  arc> (macex1 '(withs nil something))
  (do something)
  arc> (macex '(do something))
  ((fn () something))
  arc> (macex '(withs nil something))
  ((fn () something))

-----

3 points by fallintothis 6490 days ago | link | parent | on: Arc Indentation Syntax

This keeps getting brought up, but apparently it's an idea that's already been scrapped for Arc:

"I spent a couple days working on getting rid of parentheses, and it got really ugly." -- http://news.ycombinator.com/item?id=35795

-----

5 points by pg 6490 days ago | link

I just posted that code: http://arclanguage.org/item?id=2003

-----

4 points by fallintothis 6498 days ago | link | parent | on: Alphabetical List of Arc Functions

Shorter:

  (sort < (keys sig))
< compares symbols as it would strings.

-----

2 points by fallintothis 6500 days ago | link | parent | on: Arc for Ruby programmers

I think you're looking for prall, defined in arc.arc:

  (def prall (elts (o init "") (o sep ", "))
    (when elts
      (pr init (car elts))
      (map [pr sep _] (cdr elts))
      elts))
Then, you save a function and choices becomes more like:

  (def choices (menu (o result '()))
    (if menu
        (each x (car menu)
          (choices (cdr menu) (cons x result)))
        (prall (rev result) "\n" #\space)))
If having that newline at the beginning of the output is killing you, then you could also use it inside of a do:

  (def choices (menu (o result '()))
    (if menu
      (each x (car menu) 
        (choices (cdr menu) (cons x result)))
      (do (prall (rev result) "" " ") (prn))))

-----

3 points by lojic 6500 days ago | link

Cool. I also just discovered that apparently Arc#join is CL#append, so I could use join instead of cons and skip the rev.

-----

3 points by lojic 6500 days ago | link

  ; Cartesian product of elements of menu
  (def choices (menu (o result '()))
    (if menu
      (each x (car menu)
        (choices (cdr menu) (join result (list x)))) 
      (prall result "\n" " ")))     

  (choices (list
    (list "small" "medium" "large")
    (list "vanilla" "ultra chocolate" "lychee" "rum raisin" "ginger")
    (list "cone" "cup")))

-----

2 points by fallintothis 6500 days ago | link

Ah, I was wondering why append wasn't working, haha. Now I recall reading the source about how Robert Morris thought it was better to overload + for join -- which still seems to work, by the way.

Also, come to think of a nit-picky issue, optional args will default to nil = '(), so you could just as well say:

  (def choices (menu (o result))
    (if menu
        (each x (car menu)
          (choices (cdr menu) (+ result (list x))))
        (prall result "\n" " ")))
Not that it matters all that much.

One artifact I notice is that, since it returns nil but is only printing a newline at the beginning, the printout ends with "large ginger cupnil". I suppose, to avoid that in the repl, you could slap a (prn) at the end of the function definition or use the aforementioned (do ...) block. I got to thinking it might also be nice to have a prnall, but then I noticed that this is just prn:

  (def choices (menu (o result))
    (if menu
        (each x (car menu)
          (choices (cdr menu) (+ result (list x))))
        (apply prn (intersperse " " result))))
Though this could be cleaner with prnall:

  (def prnall args
    (do1 (apply prall args) (prn)))
At any rate, all these thoughts are very pedantic -- but then, so am I.

-----

3 points by fallintothis 6500 days ago | link | parent | on: Show us your Arc code

range is useful, though I kept making the goof-up of trying to pass only one arg as in Python. So, I went ahead and changed it:

  (let orig range
    (def range (x (o y))
      (if y
          (orig x y)
          (orig 0 x)))) ;could be (orig 0 (- x 1)) to be even more Python-like
Come to think of it, you could instead do something like this to be the most like Python (whether or not that's a good thing):

  (def range (start (o end) (o step 1))
    (let test (if (positive step) >= <=)
      (when (no end)
        (= end start 
           start 0))
      (if (test start end)
          nil
          (cons start (range (+ start step) end step)))))

  arc> (range 10)
  (0 1 2 3 4 5 6 7 8 9)
  arc> (range 10 1)
  nil
  arc> (range 1 10)
  (1 2 3 4 5 6 7 8 9)
  arc> (range 1 10 2)
  (1 3 5 7 9)
  arc> (range 1 10 -2)
  nil
  arc> (range 10 1 -2)
  (10 8 6 4 2)
  arc> (range 10 1 -1)
  (10 9 8 7 6 5 4 3 2)
This same idea of having the "step" parameter maps nicely into subseq syntax in Python, as I noted in this thread: http://www.arclanguage.org/item?id=479

-----

1 point by icemaze 6500 days ago | link

Everybody seems to be in love with the step parameter. Would it be such an improvement over (for instance):

  (reverse (range 10)), or
  (map [* 2 _] (range 5)) ?
Do python guys use it that often?

-----

1 point by Xichekolas 6500 days ago | link

Yeah I'd much rather compose functions than have extra parameters to remember... but I'm not a Python guy either.

-----

1 point by apgwoz 6500 days ago | link

It's pretty inefficient to use reverse, if instead you can add an extra parameter, though I guess it's often negligible.

-----


Incorporating the step parameter as in Python's indexing notation could also be interesting:

  "abcdefghijklmnopqrstuvwxyz"[10:2:-1] #=> "kjihgfed"
  "abcdefghijklmnopqrstuvwxyz"[2:20:2] #=> "cegikmoqs"
The one way that it might not work so hot in an s-expression is Python's blanking-out of indexes to indicate the default, e.g.,

  "abcdefghi"[::-2] #=> "igeca"
I'd like to see as much of this sort of range functionality as possible -- it's quite convenient -- but in an s-expression the above would be something like

  ("abcdefghi" -2) ;no distinction!
Perhaps use _ or some other symbol for the default? The cleanest would probably be to stick to the one-plus-optional-second-or-third format and just have a function that collects every nth element (then negative steps with default begins / ends would also be a chain of rev and firstn / nthcdr). Just my two cents.

-----

9 points by simonb 6500 days ago | link

To me blanking is expressed most naturally as nil.

-----


Why string interpolation when the functions take any number of parameters?

  (let var "world"
    (prn "hello " var))
Or, if you want the entire string, this + tostring (as mentioned here: http://arclanguage.org/item?id=202).

  (tostring
    (let var "world"
      (prn "hello, " var))) 
prn used alone would have a return value of simply "hello, ". With tostring, the return value is "hello, world\n".

Though it might be worth noting that in the source file, arc.arc, there looks to be the beginnings of a printf-like function:

  (let argsym (uniq)
  
    (def parse-format (str)
      (rev (accum a
             (with (chars nil  i -1)
               (w/instring s str
                 (whilet c (readc s)
                   (case c 
                     #\# (do (a (coerce (rev chars) 'string))
                             (nil! chars)
                             (a (read s)))
                     #\~ (do (a (coerce (rev chars) 'string))
                             (nil! chars)
                             (readc s)
                             (a (list argsym (++ i))))
                         (push c chars))))
                (when chars
                  (a (coerce (rev chars) 'string)))))))
    
    (mac prf (str . args)
      `(let ,argsym (list ,@args)
         (pr ,@(parse-format str))))
  )
So that you could say, apparently:

  (let var "world"
    (prf "hello, ~" var))
Granted, the hello world example isn't very illuminating as to the benefits of using prf over the regular pr / prn. But, hey, the option's there in some base form (after all, the code's rather experimental at this stage).

-----

1 point by ryantmulligan 6501 days ago | link

Why does prn only return the result of its first argument?

  arc> (prn "hello, " "world")
  hello, world
  "hello, "
Can anyone think of when this is useful at all?

-----

2 points by eds 6499 days ago | link

This is exactly how print, et al work under CL.

I suspect it is a debugging thing. Since pr and prn return their first argument verbatim you can put them in the middle of working code to find what the return value of something is, without breaking anything. As a trivial example:

(+ (prn 2) 3) ; prints 2 and returns 5

Maybe you wouldn't need it if you had a fancy debugging suite, but it can be useful if you are debugging manually.

-----

1 point by bogomipz 6501 days ago | link

I think the reason is that returning the concatenation would be very expensive. It would basically require a temporary write stream just to put together the return value. In the majority of cases, the return value is probably not even used.

To get the effect you want, simply concatenate as a separate step:

  (prn (string "hello, " "world"))

-----

1 point by akkartik 6501 days ago | link

But why not return the last element?

-----