Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dart Monocle Mustache #1889

Closed
jashkenas opened this issue Nov 23, 2011 · 28 comments
Closed

Dart Monocle Mustache #1889

jashkenas opened this issue Nov 23, 2011 · 28 comments

Comments

@jashkenas
Copy link
Owner

Good idea? https://groups.google.com/a/dartlang.org/group/misc/browse_thread/thread/611c04100ac17142

@michaelficarra
Copy link
Collaborator

See #1632 and #1708 for related issues.

edit: the syntax is related, not the goal of the feature request.

@jashkenas
Copy link
Owner Author

Right -- the interesting thing about this being that it's all about method calls and chaining, not just property merges.

@showell
Copy link

showell commented Nov 23, 2011

-1. Feels like feature creep.

This is the code that is being syntactically cleaned up:

e = someLong.expression()
e.doFirstMutation()
e.doSecondMutation()
e.doThirdMutation()

The above code seems to violate the DRY principle, but it's a case of the syntax actually revealing repetition, not causing repetition.

@satyr
Copy link
Collaborator

satyr commented Nov 23, 2011

Also see #1431.

@jashkenas
Copy link
Owner Author

And especially #1495.

@showell
Copy link

showell commented Nov 23, 2011

This is the Hemingway vs. Faulkner debate.

Nick caught the fish.
Nick cleaned the fish.
Nick ate the fish.
Nick felt good.
Nick pitched his tent.
Nick went to sleep.

@jashkenas
Copy link
Owner Author

@showell: I think you've just made the most persuasive argument in favor of local variables that I've ever heard. Nicely done.

@showell
Copy link

showell commented Nov 23, 2011

@jashkenas Thanks! I still think it's an interesting debate...I'm not completely oblivious to the benefits of nesting. But I like the way I framed it... :)

@satyr
Copy link
Collaborator

satyr commented Nov 23, 2011

Or Perl vs Python:

given (<>) {
  s/f/b/;
  print uc;
}
import sys
s = sys.stdin.readline()
s = s.replace("f", "b")
print(s.upper())

@paulmillr
Copy link

Current chaining works very well for me:

items
  .map (item) ->
    someRandomThing
    bla bla bla
    item
      .filter (inner) ->
        inner?
      .sort (a, b) ->
        a - b
      .reduce (memo, value) ->
        memo - value
  .reduce (memo, value) ->
    bla bla bla
    bla bla bla

In the cases of one-line methods it requires additional brackets, but it's still OK:

items
  .map((item) -> bla bla bla)
  .reduce(((memo, value) -> bla bla bla), 0)

So, 👎. This is creepy and strange feature.

@showell
Copy link

showell commented Nov 23, 2011

@paulmillr I am -1 like you, but just to play devil's advocate, your chaining example is slightly semantically different than the Dart proposal, which allows you to DRY up multiple calls on the same object, even if the called methods don't support chaining.

@paulmillr
Copy link

@showell hmm, you're right.

I've re-readed explanation and discussion, but it's still too strange / PERLy for me.

@satyr
Copy link
Collaborator

satyr commented Nov 24, 2011

Cascading (#1431) and chaining (#1495) are different. The Dart syntax is former.

"Smalltalk"
obj cas; cade.
obj cha in.

@TrevorBurnham
Copy link
Collaborator

Like most of the folks in this thread, I don't like the monocle mustache. Whenever I give a talk on CoffeeScript, I like to tell people that while curly braces can mean a zillion things in JavaScript, they're only used for one thing in CoffeeScript: object literals. (And destructuring assignment, which is the inverse of an object literal.) DRY cascading would be nice, but only if there were a clean, CoffeeScript-y syntax for it.

The syntax proposed by @raganwald at #1495 is powerful enough to do this, at the expense of making our whitespace rules quite a bit stricter. (I think the tradeoff is worth it.) To borrow the example from the Dart mailing list, here's how it looks under CoffeeScript now:

myTable = document.query '#myTable'
firstColumn = myTable.queryAll '.firstColumn'
firstColumn.style.background = 'red'
firstColumn.style.border = '2px solid black'
firstColumn.text = 'first column'
lastColumn = myTable.queryAll '.lastColumn'
lastColumn.style.background = blue
lastColumn.text = 'last column'

Here's how it could look under the raganwald proposal, combined with the proposal at #1407 to make implicit parentheses end at .:

document.query '#myTable'
  .queryAll '.firstColumn'
    .style
      .background = 'red'
      .border = '2px solid black'
    .text = 'first column'
  .queryAll '.lastColumn'
    .style.background = blue
    .text = 'last column'

(This is, of course, assuming that we don't actually need to keep references to myTable, firstColumn, or lastColumn.)

@raganwald
Copy link
Contributor

👍

@erisdev
Copy link

erisdev commented Nov 24, 2011

👍 for the feature; 👎 for Dart's syntax. As has been said before, we have indentation to indicate nesting levels. C:

@showell
Copy link

showell commented Nov 24, 2011

I know that CS is only superficially similar to Python, but to the extent that Python offers any kind of guidance in the realm of indentation-based languages, they were fairly conservative about overloading the semantics of indentation.

Python did eventually adopt a "with" statement, but it was more about resource teardown than syntax sugar:

http://www.python.org/dev/peps/pep-0343/

The VB "with" statement is sementically equivalent to this proposal, with slightly heavier syntax, correct?:

With testObject
    .Height = 100
    .Text = "Hello, World"
    .ForeColor = System.Drawing.Color.Green
    .Font = New System.Drawing.Font(.Font, _
        System.Drawing.FontStyle.Bold)
End With

@michaelficarra
Copy link
Collaborator

I agree with all the arguments against inclusion of this feature. -1.

@devongovett
Copy link

-1. It just looks ugly.

@breckinloggins
Copy link
Contributor

In Clojure:

(doto someObject
   (method1 withArgs)
   (method2)
   (method3))

CoffeeScript already has do so maybe a doto could work.

@alessioalex
Copy link

-1 this looks just awful, it doesn't belong in such a beautiful language like CoffeeScript

@breckinloggins
Copy link
Contributor

@alessioalex

That's why it hasn't been added yet. The reason everyone is still discussing it is the hope that, somewhere, somebody will come up with a way to do this while staying true to CoffeeScript's simplicity and beauty. Until that happens, rest assured that it won't make it into the language.

My personal opinion is that if this is going to make it in, it has to be a more general construct of which this issue is but one use case.

@ricardobeat
Copy link
Contributor

I've been using a little method added to Object.prototype, similar to the using/with syntax:

Object.defineProperty Object.prototype, "do",
  value: (fn) -> fn.call this

firstColumn = myTable.queryAll '.firstColumn')
firstColumn.do ->
  @style.background = 'red'
  @style.border = '2px solid black'
  @doSomething ->
     abc()


// squashed
(myTable.queryAll '.lastColumn').do ->
  @style.background = 'blue'
  @text = 'last column'

Of course this isn't reliable cross-browser, but it's the closest possible mapping ATM to the indentation proposal.

@erisdev
Copy link

erisdev commented Dec 5, 2011

@ricardobeat Yeah, I've been doing similar with a global returning function like Rails offers, which also has tap semantics. I don't really like changing the context, so I pass it as an argument which I can give a suitably short name.

returning = (obj, fn) ->
  fn obj
  obj

returning new Thing, (o) ->
  o.arbitrary = 37
  o.random = rand()
  …

Out of curiosity, why do you call Object.defineProperty rather than using simple assignment? Object::do = (fn) -> fn.call this works, does it not?

@showell
Copy link

showell commented Dec 5, 2011

Does it make sense to close this issue? It seems like nobody like the Dart proposal, but there are quite a few people who like the @raganwald proposal at issue 1495.

@ricardobeat
Copy link
Contributor

@erisdiscord defineProperty sets enumerable:false by default, so the added method won't show up in a for m of obj loop.

@erisdev
Copy link

erisdev commented Dec 5, 2011

@ricardobeat ooh, I hadn't thought of that. Thanks!

@jashkenas
Copy link
Owner Author

Does it make sense to close this issue?

... sure thing -- closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests