Arc Forumnew | comments | leaders | submitlogin
2 points by fallintothis 3675 days ago | link | parent

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")
  arc> (map-as 'cons [+ _ 1] '(1 2 3))
  (2 3 4)
  arc> (map-as 'string [+ _ 1] '(1 2 3))
This works because of how coerce works.

  arc> (coerce '("a" "b" "c") 'string)
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")
  arc> (map-as 'string inc "abc")
so it's not like you lose functionality, and then this post's example would've worked to begin with.

1 point by akkartik 3672 days ago | link

When you phrase it as map-as, it becomes easier to fit into my defgeneric/defmethod framework ( 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.