Arc Forumnew | comments | leaders | submitlogin
3 points by akkartik 5039 days ago | link | parent

This seems kinda sorta relevant:

"Chaining method calls is a syntax issue and not a function issue, and writing functions to return a certain thing just to cater to how you like to write programs is hacking around a missing language feature." http://github.com/raganwald/homoiconic/blob/master/2011/11/s...



1 point by rocketnia 5039 days ago | link

"One thing that expressive languages like Ruby, Smalltalk, and Lisp teach us is that many 'design patterns' are actually language smells. The 'fluent interface' design patterns is just that: A sign that a language is missing a cascading message feature."

When a language has a (sub)community that uses so many side-effectful interfaces that cascading message syntax sounds like a relief, that community-wide design pattern might be the more appropriate thing to repair. :-p

Anyway, I use my own custom infix operator for such purposes: ;it.

  -- who needs this ---
  array
    .pop()
    .pop()
    .pop()

  -- when there's this --
  var it = array  ;it.
    pop()  ;it.
    pop()  ;it.
    pop();
Just kidding around. I haven't developed a pattern in these cases, probably because I program with few side effects and few OO interfaces and because I sooner or later bury any interface I'm working with under layers of my own.

-----

1 point by Pauan 5039 days ago | link

And if you want that behavior in Arc, here's a macro:

  (mac chain (x . body)
    (w/uniq u
      `(let ,u ,x
         ,@(map (fn ((f . args))
                  ;; could use list* but Arc 3.1 doesn't include it
                  `(,f ,u ,@args))
                body)
         ,u)))
And how to use it:

  (chain path
    (move-to 10 10)
    (stroke "red")
    (fill "blue")
    (ellipse 50 50))
Though... adding in syntax sugar for it would certainly be more convenient. Come to think of it, this would be quite convenient for arc2js:

  ;; Basic DOM              
  (chain (div)
    (set-attribute "bar" "qux")
    (append-child (div)))

  ;; jQuery
  (chain ($ "foo")
    (offset 10)
    (add-class "bar")
    (click (fn ...)))
Amusingly enough, this is similar to the JS "with" block, only without all the problems that "with" has.

-----