Arc Forumnew | comments | leaders | submitlogin
1 point by fallintothis 5192 days ago | link | parent

And, what would be a simple way to do what I'm trying?

Alternatively, there's

  arc> (string (map [+ ".*" _] (coerce "test" 'cons)))
  ".*t.*e.*s.*t"
which does (almost exactly) what (apply + ...) does, but is shorter. You could also avoid the lengthy coercion and go with

  arc> (tostring (each c "test" (pr ".*" c)))
  ".*t.*e.*s.*t"
Not that either of those is optimal.


1 point by d0m 5192 days ago | link

Interesting solutions :D

There's also:

  (string (intersperse ".*" (coerce "..." 'cons)))
edit:

  (string ".*" (intersperse ".*" (coerce "..." 'cons)))

-----

1 point by fallintothis 5192 days ago | link

Except intersperse does it in the wrong order:

  arc> (string (intersperse ".*" (coerce "test" 'cons)))
  "t.*e.*s.*t"
By the way, for code that won't screw up asterisks, just prefix the line by two spaces. :)

Edit: Ah. Well, I suppose appending an extra onto the front works. Still not optimal, but oh well.

-----

1 point by d0m 5190 days ago | link

Finally, I've chosen to make a little macro:

  (let s "hello"
    (->s s 
      (map [+ ".*" _] s)))

-----

1 point by akkartik 5190 days ago | link

Can you elaborate?

-----

2 points by d0m 5189 days ago | link

This macro hide fallintothis' suggestion to my string-are-not-list problem. So basically it does:

  (def ->s (var . body) 
   `(let ,var (coerce ,var 'cons)
      (string ,@body)))
And now I can use:

  (let s "hello"
    (->s s
      (intersperse ", " s)))
  
  > "h, e, l, l, o"

-----

2 points by fallintothis 5189 days ago | link

Yet another option:

  (def map-as (type f seq)
    (coerce (map1 f (coerce seq 'cons)) type))

  arc> (map-as 'cons [+ ".*" _] "test")
  (".*t" ".*e" ".*s" ".*t")
  arc> (map-as 'string [+ ".*" _] "test")
  ".*t.*e.*s.*t"
  arc> (map-as 'cons [+ _ 1] '(1 2 3))
  (2 3 4)
  arc> (map-as 'string [+ _ 1] '(1 2 3))
  "234"
This works because of how coerce works.

  arc> (coerce '("a" "b" "c") 'string)
  "abc"
It deals with lists and strings well, which is decent: Arc's only other sequence-like type is the table (I don't think you'd ever want to treat symbols as a sequence of 1-character symbols; you'd just use a string). Tables would work better if they were properly coerced, cf. the comment above tablist and listtab in arc.arc.

The more I think about it, the more I like this model. Conceptually, it seems that map should behave like

  (def map (f seq)
    (map-as (type seq) f seq))
even if it's not implemented like that -- all the coercions would surely be slow. (Tangential: map would also need to handle multiple sequences.) But it makes more sense for map and coerce to at least have compatible behavior. Plus, map's current behavior is a degenerate case of the coerce-compatible map:

  arc> (map inc "abc")
  "bcd"
  arc> (map-as 'string inc "abc")
  "bcd"
so it's not like you lose functionality, and then this post's example would've worked to begin with.

-----

1 point by akkartik 5186 days ago | link

When you phrase it as map-as, it becomes easier to fit into my defgeneric/defmethod framework (http://www.arclanguage.org/item?id=11865). Thanks!

I've spent some time thinking about how to extend it for multiple-dispatch, and I didn't want to also think about setting the arg index to dispatch on.

-----