
Lion: Cocoa Autolayout Release Notes - cpr
http://developer.apple.com/library/mac/#releasenotes/UserExperience/RNAutomaticLayout/_index.html#//apple_ref/doc/uid/TP40010631
======
kenferry
Some of that document is out of date - Interface Builder does have support for
Auto Layout now. Auto Layout also has a space now. ;-) I like to spell it
[Auto]-[Layout] (see the ASCII art programming language part of that
document).

People may also be interested in the WWDC session on Auto Layout:
<http://goo.gl/5sSgK> (requires free developer account).

Some interesting aspects of the system to me:

(1) The use of fairly simple but freeform constraints. The numerical solver is
based on work in this paper, <http://goo.gl/6fHdd>. They end up covering
really a lot of stuff you want to do in a natural way, and with a single
constraint object with few properties.

(2) The emphasis on visualization. Most of the time constraints are created
visually, in Interface Builder, by dragging objects around and snapping them
together. When doing layout in source code, you use an ASCII art inspired
format string that visually looks like the interface you're trying to create.
When debugging at runtime, you can ask a window to draw constraints on screen,
so that you can see what they are. (The debugging support itself is also
interesting.)

(3) The reworking of how layout fits into Cocoa's model-view-controller
design. Previously, too much was in the controller layer - to do layout you
ended up having to say things that you didn't really know, because it was data
intrinsically known by the view layer. By reworking the layering, the views
can take responsibility for those aspects of layout that are intrinsically
known to the view. This takes a lot of pressure off, because (a) you don't
have to specify things you don't know, (b) there's less work to do because the
views are doing some of it, (c) a lot of the time the views are coming out of
AppKit, so you never have to write the view parts at all. It also aligns the
easiest thing to do (don't mess with the views) with the right thing to do
(use standard OS behavior). If you want to make it do something unusual, you
can, but you have to say so. Your code records the places you intentionally
deviated.

[Disclosure - I worked on this.]

~~~
dirtyaura
_> When doing layout in source code, you use an ASCII art inspired format
string that visually looks like the interface you're trying to create._

This is a cool idea. Instead of specifying layout inside strings, did you
consider syntactic sugar or macros to do it in code?

~~~
kenferry
Yes… let's talk macros first. Actually, first first you should look at multi-
dimensional analog literals if you haven't seen it,
<http://weegen.home.xs4all.nl/eelis/analogliterals.xhtml>. Awesome/yikes.

Okay, back. What are the reasons to consider macros? Probably, compile time
checking and ability to directly use variables that are in scope (e.g.,
fooButton for some button).

The goal of compile time checking is really debugging, to make it easy to find
and fix mistakes. Now, in a format string, we don't have compile time
checking, but we can have really good, descriptive error messages. Our
diagnostics were inspired by those in clang,
[http://blog.llvm.org/2010/04/amazing-feats-of-clang-error-
re...](http://blog.llvm.org/2010/04/amazing-feats-of-clang-error-
recovery.html), right down to the carat pointing at the problem within the
code. Maybe we could have done that with macros? I guess I didn't really try
that hard, but usually if you mess up a macro, you're going to get something
really cryptic from the compiler. Also, it's wayyyy easier for the client to
grok and feel comfortable with a format string than with a crazy macro system.
You know how we're parsing the string. You could implement it yourself if you
had to. It's understandable, and you can see that there won't be side effects.
Now consider that multi-dimensional analog literals link above. Does it work?
Heck yeah! Do you want black magic like that in your code, with behavior you
don't understand (at least without way more investment in understanding than
we want to require)? Probably not! Plus, we're likely to have to compromise on
the visual design of the language now and/or in the future to contort it into
what's technically possible in macros over ObjC. This will also hurt
debugging, in that you'll be less likely to quickly understand what your code
says. So for debugging, I don't think macros are actually going to be a win,
despite the compile time checking. And really, the above concerns are enough
to kill macros for me.

Plus, we might be able to recover most of the compile time checking anyway.
I'd love to see clang's __attribute__ format extended to do checking of Cocoa
visual format strings. [http://gcc.gnu.org/onlinedocs/gcc/Function-
Attributes.html#i...](http://gcc.gnu.org/onlinedocs/gcc/Function-
Attributes.html#index-Wformat-2426). We have a bug tracking this.

Ability to directly use variables is a positive for macros. As is, we have to
pass a dictionary on the side that maps identifiers to actual view objects. In
python you could pass locals(), but ObjC doesn't maintain a symbol table at
runtime. For this we actually do pull a skankier-than-usual macro trick to
make things easier.

    
    
        id views = NSDictionaryOfVariableBindings(fooButton, barButton);
    

expands to something equivalent to

    
    
        id views = _NSDictionaryOfVariableBindings(@"fooButton, barButton", fooButton, barButton, nil);
    

and _NSDictionaryOfVariableBindings parses the comma separated string to make
a dictionary mapping @"fooButton" -> fooButton.

    
    
        #define NSDictionaryOfVariableBindings(...) _NSDictionaryOfVariableBindings(@"" # __VA_ARGS__, __VA_ARGS__, nil)
        APPKIT_EXTERN NSDictionary *_NSDictionaryOfVariableBindings(NSString *commaSeparatedKeysString, id firstValue, ...); // not for direct use
    
    

Okay, last, why not make this an actual part of Objective-C, like regexes are
in some languages or like LINQ is in C#.

I feel like the reasoning here is more wishy-washy, so I don't know, maybe
it's wrong and we'll revisit it. Our system has a continuum from leaf code on
which nothing else depends, like apps, down through AppKit, Foundation, and
Objective-C. The continuum isn't really defined by what framework some code is
in, it's defined by how much sits on top of it in the dependency stack. As you
go down toward the deeper and more built-upon parts of the system, reliability
becomes more and more important, and our ability to cheaply change our minds
if an interface isn't working out goes down. The standards for simplicity and
wide applicability go up and up. Objective-C's deep. You can literally learn
_all_ of Obj-C in a weekend if you know C. We like that. In recent releases we
have relayered things like memory management (GC, ARC) and properties from
being framework conventions to being formal parts of the language. But that's
where the language is right now. There's a pretty clear divide between
language and framework, and the language doesn't reach up and violate the
layering much. If we're thinking about moving something like these layout
format strings into the language, we should also be thinking about printf-
style format strings (or other templating), Core Data predicates, regular
expressions and lots of other Cocoa-ness - basically obliterating the
existence of any kind of layer boundary between ObjC and Cocoa. These would be
extremely controversial changes, inside and outside of Apple. That doesn't
necessarily make them wrong, but I'm not confident they're right. Anyway, it's
something that could be considered in the future.

~~~
Someone
In my/the ideal world, clang would have some plugin feature where it knows
that it must pass that string to some external DLL for validation. Ideally,
that DLL should be able to generate code (just as the C preprocessor), but I
fear that would require quite some interface between plug-ins and clang.

I think it already would be a big win if that DLL only could use the compiler
state to issue error messages.

Open problem is how clang would know that a string needs external validation.
I think a variant on the @"string" format might work:

    
    
        id myConstraint = @layout"[button]-[textField]";
    
        id myRegex = @regex"^[a-z]+$";
    

(I say might because the C++ grammar has some corners that may deliver
surprises here; with (im)proper function overloading, the compiler might find
a way to interpret @layout as taking the address of layout)

The link between prefix and DLL should be a command-line argument to clang.
Problem, of course, is that you give up compatibility with other compilers.
Also, this is more clunky than it needs to be; in a 'proper language' like
Lisp the integration would be seamless.

------
jamesaguilar
The syntax is crazy, but brilliant. I would never have thought of it myself,
but now that I've seen it it's obvious.

The main thing I wonder is whether the syntax is supported by vanilla
objective c, or if Apple is cheating a little (i.e. building support for new
hotness into the compiler).

~~~
zedshaw
I did this years ago, in a project called Claro, and then again in
<http://ihate.rubyforge.org/profligacy/lel.html> and pretty much every GUI
framework I've done. I got the idea from Wiki syntax and the Cassowary
constraint solver as well as Knuth's algorithm.

Apple's done nothing original here.

~~~
stephth
This is awesome. This concept of building elastic layouts with ASCII code is
new to me and I agree with @jamesaguilar that it's one of those obvious yet
genius ideas.

Has anything been done towards this direction to generate CSS layouts? It
seems like it could cure some headaches.

~~~
rufo
Yep: <http://www.w3.org/TR/css3-layout/>

------
vdm
Current documentation (as of 2011-07-06):
[http://developer.apple.com/library/mac/#documentation/UserEx...](http://developer.apple.com/library/mac/#documentation/UserExperience/Conceptual/AutolayoutPG/Articles/Introduction.html)

Demos:
[http://developer.apple.com/library/mac/#samplecode/Cocoa_Aut...](http://developer.apple.com/library/mac/#samplecode/Cocoa_Autolayout_Demos/Introduction/Intro.html)

------
gfodor
The first time I saw compiled constraint based mini-languages like this was in
OpenLaszlo:

<http://www.openlaszlo.org/>

It's one of the most brilliant yet underappreciated bits of software I've come
across. Are there others?

~~~
SimHacker
I love the constraint system in OpenLaszlo too, and I've used OpenLaszlo for
many projects. The "Garnet" user interface system, developed in the 90's by
Brad Meyers at CMU, also has constraints for laying out user interfaces. I
worked on both Garnet at CMU and OpenLaszlo at Laszlo Systems. Here's a
description and comparison of the two systems, that I wrote a while ago:

Constraints and Prototypes in Garnet and Laszlo:
<http://www.donhopkins.com/drupal/node/69>

"Once you've tasted a programming language with constraints, you will not want
to go back. Programming without constraints is like writing in machine
language: error prone, low level, tedious, inefficient and mind numbing."

"Constraints are like structured programming for variables: In the same way
that it's better to use loops and conditionals instead of gotos, it's also
better to use declarative programming that says what you mean, instead of
imperative peeks and pokes and side effects."

A description of OpenLaszlo:

What is OpenLaszlo, and what's it good for?
<http://www.donhopkins.com/drupal/node/124>

I also worked briefly on a cross platform gui system called Galaxy, for a
company called Visix, which had a constraint system called "springs and
struts". But it turned out they were evil so I left. (The company, not the
springs and struts. ;)

------
marchdown
The whole boxes-and-glue model reminds of TeX. Sure, constraint-based layout
models are nothing new, but here we've got some specific similarities: line-
based processing, optional arguments (H|V) in front, and especially
priorities. Assigning priorities to different constraints is what allows TeX
to degrade gracefully... before manifesting myriads of hard-to-trace bugs.

------
fomojola
Is this really the first constraint-based layout system in OSX land?

~~~
kenferry
No. The existing Cocoa system was constraint based too, just more restrictive
constraints (view to superview only). CoreAnimation had a constraint based
layout system, Carbon had a constraint-based system.. just "constraint-based"
doesn't capture what's interesting.

------
keyle
Ok. Still miles away from what WPF proposes...

~~~
mullr
The WPF system is hierarchical rather than constraint-based. I've done a
variety of complex (I mean really complex) WPF layouts that need to scale, and
they're complex and fiddly. In many cases I would rather have had a constraint
system. When you try to align things to a layout grid in any way, for example,
it becomes very awkward.

But it's not clear to me constraint-based layout deals well with dynamic
content; this may be a tradeoff.

~~~
thesz
I was told that WPF could produce "swastika" layouts. Ie, something along the
lines:

    
    
            aaaaa bb
            aaaaa bb
                  bb
            dd    bb
            dd    bb
            dd
            dd ccccc
            dd ccccc
    

This is as tabular as "grid" from Tk. You can resize any of "a", "b", "c" or
"d" widgets and everything will resize accordingly.

So I have an impression that WPF is constraint-based.

------
berntb
This document is too long to read on a screen (yes, I'm old). I got it into
Instapaper, but would prefer physical paper.

Is there a link to a pdf version or something, somewhere?

