Arc Forumnew | comments | leaders | submitlogin
macro / function question
3 points by bOR_ 6165 days ago | 9 comments
I wonder how I can write a macro or definition that understands that if I ask for

  (twodimlist 0 3)
That i want

  ((twodimlist 0) 3)

As there doesn't seem to be any syntax that I can alter to achieve this, the only option I see is to write a function like this:

  (def ls (list x y) 
    ((list x) y))
but as my knowledge about macros is about 2 hours old, I might have missed a way to learn arc (listname 0 3).


1 point by kennytilton 6164 days ago | link

Sorry, my Arc is rusty, did you mean:

  (def ls (x y) ((list x) y))
My next question would be what that has to do with your original query, and my question there would be what does this do?:

  ((twodimlist 0) 3)

-----

1 point by bOR_ 6164 days ago | link

I've a function that binds a list of lists to to variable 'world', and a function that prints out this world.

  (def makeworld (x)
    (let z nil
      (repeat x (= z (cons nil z)))
      (repeat x (= z (map [cons nil _] z)))
    (= world z)))

  (def show ()
    (each x world
    (each y x
    (pr (if (is y nil) #\. y) #\space))
    (pr #\linefeed)))
The world can then be seeded with trees, or shrubs or monsters or whatever. Anyway, as the world is a list of lists, it functions as a two-dimensional array.

If in arc I want to access a point in this two-dimensional list / array, I need to enter ((world 0) 3), and the basic question was how to change arc (macrowise) to make (world 0 3) be equivalent to ((world 0) 3). I already worked around it by now.

To answer your question: you're assuming that there is a list called 'list', and in my initial example I described a function that took the name of the list as first argument.

-----

2 points by fallintothis 6163 days ago | link

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.

-----

1 point by kennytilton 6164 days ago | link

Oh, I get it. No, this is not something you can do with macrology because there is no room for a macro in your desired syntax (where you just want the list itself and the index values). As you say, if you'll make room for another token it can just be a function (which would be fun to generalize to N dimensions). As for making ((list (list 42)) 0 0) return 42, I think you need to is suggest it as a (very reasonable) enhancement to Arc.

-----

2 points by pg 6164 days ago | link

I don't understand exactly what this code is for, but I think you could write makeworld as

  (def makeworld (x)
    (= world (n-of x (n-of x nil))))

-----

1 point by t1m 6165 days ago | link

Does this work...

  (mac twodimlist (x y)
    `((twodimlist ,x) ,y))

?

-----

1 point by kennytilton 6164 days ago | link

I see you have corrected the above by switching to a different name (a reasonable way to go) but it might be fun to see if you can stick with one and expand differently based on whether one or more than one value is supplied (meaning of course you need to support what we call &rest in CL in the parameter list of twodimlist. What I do not know is how well Arc likes to expand a macro into code referencing the same macro.

-----

1 point by t1m 6165 days ago | link

Oops, ignore the above. How about this...

  arc> (mac blah (n x y) `((,n ,x) ,y))
  #3(tagged mac #<procedure>)
  arc> (macex1 '(blah twodimlist 0 3))
  ((twodimlist 0) 3)

?

-----

2 points by sjs 6163 days ago | link

Arbitrary number of arguments:

  (mac drill (lst . xs)
    (if (no xs)       `,lst
        (no (cdr xs)) `(,lst ,(car xs))
        `((drill ,lst ,@(rev (cdr (rev xs)))) ,(last xs))))

-----