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

What operators should the DSL use? #1

Closed
ahti opened this issue Jun 5, 2014 · 10 comments
Closed

What operators should the DSL use? #1

ahti opened this issue Jun 5, 2014 · 10 comments

Comments

@ahti
Copy link

ahti commented Jun 5, 2014

This is a (imho) pretty important design decision: What operators do we use for expressing constraints?

There are basically three different kinds of operators needed. One for expressing the kind of relationship, another for the factor and one for the constant.

For factor and constant, I would say that *, / and +, - are simple and good choices, since they express perfectly well what they are supposed to do.

For the kind of relationship I am not sure.

We could use ==, <=, >=. These are understandable, but have (again, imho) one problem: They are seldom, if ever, used to do something. Usually, they are always only used to test for something, and do not, in and of themselves perform any action (such as creating a constraint).

So the alternative is to come up with another set of operators different from the comparison operators, and thereby make it clear that these are not normal comparisons and do in fact do something.

I think what this decision boils down to is the following question:

Does the programmer describe a set of checks that the system then tries keep true, or does he explicitly create constraints? Does he say "this attribute should always be equal to that attribute" or does he say "make this attribute equal to that attribute"?


PS: If we choose to invent new operators, we have these characters to play with: / = - + * % < > ! & | ^ . ~, and I would say it'd be a reasonable choice to take ==, <=, >= and prefix them with one of those characters.

@iwasrobbed
Copy link

It does seem strange at first with ==, <=, >= being used to do something rather than as comparison operators, but after all it is a DSL so I think it's pretty clear once you use it a few times. Although personally I would use = in place of == if possible (unless you can't overload that one).

My vote would be to use those operators rather than prefixing them with another character and just assume a short learning curve at the cost of immediate clarity for new users.

@cloudkite
Copy link
Contributor

The other downside to using equality operators is that it will take away the ability to use them for actual comparison ie you won't be able todo if (constraint1 >= constraint2) Although having said that rather unlikely that you want to compare constraints.

I quite like the idea of substituting = with ~
~~ >~ <~

~ is usually used to indicate a larger, possibly significant, degree of error.

That sounds like our beloved AutoLayout ;)

A few other possibilities to throw into the mix

  • --- --> <-- (looks bit too like a closure?)
  • |==| |>=| |<=| (wrap equality operators)
  • &= &> &<

I think ^ could be used to express the priority of a constraint.

@iwasrobbed you can't overload certain operators including the = operator

@cloudkite
Copy link
Contributor

a few examples

installConstraints([
    view1.left ~~ view2.left + padding
    view1.edges <~ superview.edges - padding
])

@iwasrobbed
Copy link

Another possibility: Using || for equalsTo (two plane surfaces attached to each other), >>=, and <<= (or >== and <== instead)

installConstraints([
    view1.left || view2.left + padding
    view1.edges <<= superview.edges - padding
    view3.edges >>= view1.edges - padding
])

@nickynick
Copy link

I would advocate for ==, >= and <=, because in this case the constraints code reads effortlessly. Having used accustomed equality symbols, you will never stumble, thinking "Hey, what is ~~ supposed to mean? Oh right, equality. And what is the symbol for less-than-or-equal-to, again?". I honestly don't think this is confusing because, well, this is DSL, not just your regular code.

@cloudkite
Copy link
Contributor

@nickynick I agree it would a bit harder to digest at first. However it does have the advantage of clearly distinguishing layout constraint equations from equality statements. Consider the following code

if self.layoutType == Expanded {
    view1.left ~~ view3.left + padding
} else {
    view1.left ~> view2.left + padding
}

Where as here the line between what is a constraint and what is an equality statement is kind of blurred

if self.layoutType == Expanded {
    view1.left == view3.left + padding
} else {
    view1.left => view2.left + padding
}

@ahti
Copy link
Author

ahti commented Jun 6, 2014

I like ~~, to me it looks a bit like "tying the two sides together" 👍

@robertjpayne
Copy link
Member

I agree with @nickynick and using == <= >= overloaded operators where they make sense are fine, it's when people starting using == to combine two objects and return the result or some weirdness.

@joachimboggild
Copy link

A comment: @nickynick and @robertjpayne : It might not be clear to a developer that he is in fact using a special "language"/DSL in these specific lines of code, and for that reason using the equality operators should be avoided.
It becomes clear that a DSL is used only when the programmer sees the special characters.
I vote for exchanging =with ~

Another thing: The overloaded operators are not obvious when using code completion - I hope that these operators are not the only way to specify the relationships? The "old" way with view1.edges.equalTo(xxyy)still works, right?

@cloudkite
Copy link
Contributor

@joachimboggild Yup we decided to keep this repository as a swift version of the Masonry syntax since there are already a couple of good options for operator overloading see
https://github.com/nickynick/Tails and https://github.com/robb/Cartography

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

No branches or pull requests

6 participants