Hacker News new | past | comments | ask | show | jobs | submit login
Humans are not constraint solvers (amigueloferreira.pt)
83 points by miguelferreira on Oct 13, 2014 | hide | past | favorite | 27 comments



Disclaimer: I was the owner and maintainer of autolayout at Apple for a few years. I think the article makes a fair point, but focuses on just a detail.

The article criticizes what it calls "source-order independence" where "you can have two unrelated components be involved in a constraint." We called this "cross-cutting constraints," and discouraged their use for exactly the reason the author gives. Most constraints attached to you should be to yourself, a sibling, or a parent. Cross-cutting constraints are not a primary benefit of constraint-based layout.

So what do constraint-based layouts give us? A key one is that constraints regularize layout under a uniform language. You are given a handful of properties (width, height, two centers, four edges, and baseline) and constants, and can relate them using equalities, inequalities, and priorities. From those primitive elements, you can build a lot of stuff that other frameworks handle in an ad-hoc manner.

Want to set a fixed width? Equate the width to a constant. Make it a minimum width? Change the relation to >=. Right align? Equate the two right edges. Centering? Equate the two centers. Two containers ought to have equal widths? Relate their widths to each other. Aspect ratio? Relate the width to the height. All this stuff just falls out naturally, requiring no special support.

Compare to CSS, which supports many of these features, but in a completely arbitrary, ad-hoc way. Right-aligning requires setting a position, but center-aligning requires setting margin-left and margin-right, and vertical centering requires a completely different set of hackish techniques. Or compare to Android, which has lots of ad-hoc methods to achieve specific layout tasks (setMeasureWithLargestChildEnabled, setBaselineAligned, etc).

Autolayout has its share of problems: it's verbose, has a steep learning curve, works poorly with grid-type layouts, struggles with nonlinear layouts like text reflowing, and more. But its approach of a uniform layout language is powerful and elegant, compared to ad-hoc "bag of properties" layout mechanisms.


Autolayout is definitely planned out better than the jumble of thoughts and improvements that has become CSS. Personally, my biggest issue was the learning curve, like you said. Trying to do very simple layouts (that were trivial on older versions of iOS/XCode) required a lot of reading through documentation just to get started. And a lot of fighting with strange errors I hadn't seen before. I imagine that as the XCode constraints/layout UI continues to improve this will be less of an issue.


In my experience, android layout is significantly easier to 'get right' and significantly more understandable at a glance than iOS autolayout. I really like what autolayout is trying to accomplish, but it isn't at the level of Android for me yet (I really like the idea of the visual format, however). I appreciate that the constraint system is a general solution to the problem, but, as we see in the grid layout case, sometimes specific solutions are a better answer.

We do all our iOS layout in code, and all our Android layout in XML (or all that we can, save the 1% that necessitates munging in the Java). This probably affects my opinion, since Java layout code for Android is just as obtuse as the objective-c autolayout, if not more so.


I'm a weird case (electrical engineer with ~a BSc in CS as well). When I first saw the WWDC 2012 sessions about AutoLayout, I was blown away! After all these years dicking around with specific pixel sizes for things, and basically doing my own linear constraint solving on paper to make things work (web, mobile, desktop, etc), I just breathed a sigh of relief to see that it was finally done the right way. I've since done a few layouts with it and am super impressed, especially with the text DSL for specifying constraints. Sure, it's a little finicky sometimes, but that's generally when I haven't thought through the constraints well enough :)


Another thing to keep in mind is that while cross-cutting constraints are a bad idea in gross quantities, they do appear in many well-designed UIs and as such are not something that you can disallow completely. If you have a system that doesn't support them (such as Android), you force developers to kludge their own constraint solving on top of the existing system. The occasional need for such things isn't going to go away if you structure your framework correctly, it's just a question of how much you're going to make your developer hate you when they need to implement one.


Actually CSS is not arbitrary. I don't know what you mean by "setting a position" but if you use float to right or left align an element, it will cause text to wrap on the opposite side. How would text wrap on float: center? It doesn't make sense, that's why you'd just want blank space on each side (hence margins.)

Everything else works well with absolute positioning. Need something vertically aligned?

    position: absolute;
    top: 50%;
    margin-top: (1/2 height of element)


as mentioned in another comment this only works if you know the height. Your example is exactly the issue that the original comment was talking about.

Your intention is to align both centers. Why do we need to be dealing with 'top' and 'margin-top' to achieve this? It is a poor way to describe your intention.

It's much easier to say:

  box1.center == box2.center
The cassowary solver allows you to specify exactly your intentions in relation to the edges and centers of boxes. It's easier to reason about and doesn't require the bag of weird tricks that are needed in CSS (eg. margin: 0 auto; to center??? wtf?)


What if you can't know the height of the element?


CSS has one main problem w.r.t. layout: it does not have a universal way of specifying whether the size of an element should be determined by its contents or its container. So you can say, for example, "Make this element take up the remaining horizontal space" (that's the default for display:block) or "Make this element just wide enough and just tall enough to contain its contents" (the default for display:inline) but it is not possible to say, "Make this element tall enough to consume the remaining vertical space." The result is that some simple layouts (e.g. a fluid layout with same-height columns underneath a header with dynamic content) are not possible in CSS. All this could be solved by simply allowing the user to specify width and height of an element in terms of either the element's contents or the element's container (or, of course, as a fixed size).


> it is not possible to say, "Make this element tall enough to consume the remaining vertical space."

As of just a few months ago, it is. Look into the now-almost-standardised (last call working draft) version of flexbox, which is implemented in recent versions of Firefox and Chrome, and also IE11.

An example of what you say is impossible, in just a few lines of CSS: http://philipwalton.github.io/solved-by-flexbox/demos/sticky...


It looks like you edited your comment. The original link was:

http://philipwalton.github.io/solved-by-flexbox/demos/holy-g...

and now it is:

http://philipwalton.github.io/solved-by-flexbox/demos/sticky...

The latter is not what I described, and I can't get the former to work even in the latest Firefox.


Oops. I read what you said and thought the current one matched what I quoted better - sorry.

I'm using Firefox 32.0.3, and both examples work for me perfectly. I'm not sure what the issue is.


Both work for me fine, too. Latest Firefox on Debian.

According to: http://css-tricks.com/snippets/css/a-guide-to-flexbox/ Firefox should work from v22 on.


flexbox support for mobile browsers is still pretty terrible.


Better yet, the size and position of an element should always be determined by the parent, but the parent may query the child for information that the parent can use to determine the sizes and positions.


There are two issues here. One is doing layout with a constraint solver. The other is the user interface for the person doing the page layout.

A constraint solver interface is a good match to a GUI. It's not a good match to a textual interface. Web designers should be using a layout tool like Dreamweaver, not hand-coding constraint expressions.

For an example of a constraint-based tool for a much harder problem, see Autodesk Inventor, which is a 3D CAD system. It has 2D sketches, and those are controlled by constraints. You can draw rectangles, and if they have coincident points or edges when drawn, those are constrained to stay together. You can explicitly dimension something, and it becomes that length. If you try to apply inconsistent constraints, the system rejects them. You can make all constraints visible as icons, then delete any you don't want. Web designers would probably love the power of Inventor sketch mode, because it's not restricted to horizontal and vertical lines, or even to straight lines. That might be overkill for web design, although being able to wrap text around a curved image would make some people happy. Inventor demonstrates that a much harder constraint problem than web design has been successfully solved with a good GUI.

Asking visual designers to write constraint expressions by hand is pounding a screw with a hammer. Use the right tool for the job.


I don't understand the title. Humans are constraint solvers (I have personal experience in this), although they are not fast at it, so humans also use constraint solvers.

If you don't have a constraint solver in your layout engine, you had better be a good one yourself, because somebody has to do it.


And yet that is exactly the direction that Computer Aided Design - such as Autodesk Inventor & Dassault SolidWorks - has gone in. And it makes building things a shit load easier, let me tell you.


I don't think there is a single way to do layout that is perfect for all needs. Both CSS style layout and Autolayout work well for many cases and fail miserably for others.


I never could get onboard with constraint based layouts. It feels like someone got a little too clever and really over-solved a problem. Realistically, you want your content to look decent on small screens (phones), medium sized screens (tablets), and fill larger ones (everything else). In the case of iOS dev you really have 3-4 specific targets. CSS media queries (or 2-3 nibs with boxes and springs) solve this problem adequately. Trying to create a system of linear inequalities that guarantees perfection on every possible resolution is just asking for mistakes and headaches. I agree with the author that most of the "power" lays in a space of things you really don't want to touch.


Isn't the real question whether humans are good at generating constraints?


* maintainable contraints


Yes. But that still doesn't necessarily mean solving, provided you can actually constrain everything you care about, which I'd guess you probably can't...


It’s a rhetoric device (a hyperbole) which hints to maintainability issues. That’s how I understood it.


Yeah, I didn't mean my comment to be a devastating take down. I just find it frequently useful to try and state things more clearly and correctly when faced with hyperbole.


If somebody writes an incomprehensible sentence it's not his language's fault for him doing so - and the solution is not to simplify English.


All you need to understand this problem is better language.

All of this has been solved long time ago at Java Swing. Checkout Mig Layout.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: