<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
I just saw these replies while searching for this thread, as I've
been thinking of this proposal again recently.<br>
<br>
Regarding the API you point out, would it not be more appropriate
for the API to change to provide an object conforming to some
protocol definition instead? I don't like the idea of possible
language changes being held back just because of some poorly defined
APIs that were designed for a different language. Objective-C and
cocoa frameworks have been changing a lot in the past two years to
better interoperate with swift, and I don't see this example as
something that needs to be handled at all differently.<br>
<br>
That said, if there are too many of these kinds of examples in
Apple's frameworks to completely resolve, would a more explicit use
of the feature be palatable? I mentioned in another branch of this
thread that if it is absolutely necessary to keep this behavior
around, it could be separated from AnyObject, perhaps into another
protocol called something like ObjcObject, so that code would need
to do something like this to compile and work:<br>
<font face="Courier New, Courier, monospace"><br>
let thing: ObjcObject = treeController.arrangedObjects() <br>
let nodes = thing.childNodes?()</font><br>
<br>
Unless theres a lot of pushback or it's too late for this kind of
change to go into Swift 3, I'd like to make some kind of proposal
along these lines.<br>
<br>
- Kevin<br>
<br>
<div class="moz-cite-prefix">On 4/18/2016 11:12 PM, Charles Srstka
via swift-evolution wrote:<br>
</div>
<blockquote
cite="mid:46230E2E-B774-4A9D-8137-5CC526397C14@charlessoft.com"
type="cite">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<div class="">Making things optional is fine; I would, however,
like to give a strong -1 to the original proposal in which
everything would have to be cast to an explicit type, since
Cocoa contains APIs that give you objects of opaque types,
returned as id/AnyObject, and expects you to be able to call
methods on them. For example, -[NSTreeController
arrangedObjects] returns an id/AnyObject which the documentation
promises will respond to -childNodes and
-descendantNodeAtIndexPath:, but no type information is given.
If the original proposal were implemented, this API would become
impossible to use from Swift.</div>
<div class=""><br class="">
</div>
<div class="">Charles</div>
<br class="">
<div>
<blockquote type="cite" class="">
<div class="">On Apr 18, 2016, at 10:01 PM, Joe Pamer via
swift-evolution <<a moz-do-not-send="true"
href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>>
wrote:</div>
<br class="Apple-interchange-newline">
<div class="">
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8" class="">
<div style="word-wrap: break-word; -webkit-nbsp-mode: space;
-webkit-line-break: after-white-space;" class="">Just an
update on this… (Sorry about the delay!)
<div class=""><br class="">
</div>
<div class="">After experimenting with the changes
outlined below, and discussing the matter with a few
folks off-list, it seems like a better compromise would
be to only adopt option #2. We would keep the direct
member access syntax and wrap the results of any dynamic
member access expressions in an Optional, as opposed to
an IUO. In practice this feels like a nice compromise
that will prevent many users from shooting themselves in
the foot, as changing the wrapping to optional forces
users to immediately account for failures without having
to jump through too many hoops.</div>
<div class=""><br class="">
</div>
<div class="">Thoughts?</div>
<div class=""><br class="">
</div>
<div class="">Thanks!</div>
<div class="">- Joe</div>
<div class=""><br class="">
<div class="">
<blockquote type="cite" class="">
<div class="">On Mar 23, 2016, at 12:45 PM, Joseph
Pamer <<a moz-do-not-send="true"
href="mailto:jpamer@apple.com" class="">jpamer@apple.com</a>>
wrote:</div>
<br class="Apple-interchange-newline">
<div class="">
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8" class="">
<div style="word-wrap: break-word;
-webkit-nbsp-mode: space; -webkit-line-break:
after-white-space;" class=""><br class="">
<div class="">
<blockquote type="cite" class="">
<div class="">On Mar 23, 2016, at 11:29 AM,
Jordan Rose <<a moz-do-not-send="true"
href="mailto:jordan_rose@apple.com"
class="">jordan_rose@apple.com</a>>
wrote:</div>
<br class="Apple-interchange-newline">
<div class="">
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8"
class="">
<div style="word-wrap: break-word;
-webkit-nbsp-mode: space;
-webkit-line-break: after-white-space;"
class="">
<div class="">The most common use case
I've seen for this has been drilling
into a heterogeneous collection
without specifying intermediate types,
i.e.
`pluginProperties["actions"][0]["name"]`.
Some possible variations on this
proposal could continue to allow that:</div>
<div class=""><br class="">
</div>
<div class="">- Remove all lookup except
the subscripts `(AnyObject) ->
AnyObject?` and `(Int) ->
AnyObject`.</div>
<div class="">- Instead of removing
AnyObject lookup completely (the
proposal), change the IUO-wrapped
results (the current behavior) to use
Optional, requiring developers to
explicitly deal with the possibility
of failure.</div>
<div class="">- Both of the above.</div>
<div class=""><br class="">
</div>
<div class="">I know Joe Pamer has been
looking into seeing how this feature
is used by introducing a warning for
it in the type checker. Before making
any changes here we'd want to know how
it affects real-world projects.</div>
</div>
</div>
</blockquote>
<div class=""><br class="">
</div>
<div class="">I should be pushing a branch
that does both of the above “real soon now”.
(This branch also includes my recent
experiments in inhibiting implicit bridging
conversions.) I’ll be curious to know what
people think once they’ve had a chance to
play with these changes.</div>
<div class=""><br class="">
</div>
<div class="">Thanks!</div>
<div class="">- Joe</div>
<br class="">
<blockquote type="cite" class="">
<div class="">
<div style="word-wrap: break-word;
-webkit-nbsp-mode: space;
-webkit-line-break: after-white-space;"
class="">
<div class=""><br class="">
</div>
<div class="">Jordan</div>
<div class=""><br class="">
</div>
<br class="">
<div class="">
<blockquote type="cite" class="">
<div class="">On Mar 22, 2016, at
18:59 , Kevin Lundberg via
swift-evolution <<a
moz-do-not-send="true"
href="mailto:swift-evolution@swift.org"
class=""><a class="moz-txt-link-abbreviated" href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></a>>
wrote:</div>
<br
class="Apple-interchange-newline">
<div class="">
<meta http-equiv="Content-Type"
content="text/html;
charset=utf-8" class="">
<div style="word-wrap: break-word;
-webkit-nbsp-mode: space;
-webkit-line-break:
after-white-space;" class="">In
"Using Swift with Cocoa and
Objective-C", this behavior is
described as part of how
AnyObject works:
<div class=""><br class="">
<div class="">
<div class=""><i class="">“You
can also call any
Objective-C method and
access any property
without casting to a
more specific class
type." … "However,
because the specific
type of an object typed
as AnyObject is not
known until runtime, it
is possible to
inadvertently write
unsafe code. As in
Objective-C, if you
invoke a method or
access a property that
does not exist on an
AnyObject typed object,
it is a runtime error.”</i></div>
<div class=""><br class="">
</div>
<div class="">I propose that
we remove this behavior
entirely to push swift
further in the direction
of type safety.</div>
<div class=""><br class="">
</div>
<div class=""><b class="">Rationale:</b></div>
<div class="">Even if you
don’t mean to write code
that relies on this
behavior, it's easy to
accidentally do so when
interfacing with various
Cocoa APIs due to type
inference. A developer may
not even realize that
their code is unsafe since
their code will compile
just fine when calling
obj-c visible methods.
Removing this behavior
would alleviate any
confusion that a developer
may have while writing
this, especially as it is
not a highly advertised
feature of AnyObject.
Furthermore, anyone who
reads swift code using
this will know with more
certainty what types the
author expects to be using
here since an explicit
cast will be required.</div>
<div class=""><br class="">
</div>
<div class=""><b class="">Considerations:</b></div>
<div class="">If this is
done, the way I see
AnyObject behaving is
similar to Any, where you
need to manually downcast
in order to call methods
on things. Code would
change from this:</div>
<div class=""><br class="">
</div>
<div class=""><br class="">
</div>
<div class="">class Foo:
NSObject { func bar() {} }</div>
<div class="">
<div class="">let things =
NSOrderedSet(object:
Foo())</div>
<div class=""><br class="">
</div>
<div class="">for thing in
things { // thing is
AnyObject</div>
<div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>thing.bar()
// happens to work but
not verified by
compiler, may crash in
the future</div>
<div class="">}</div>
</div>
<div class=""><br class="">
</div>
<div class=""><br class="">
</div>
<div class="">to something
like this:</div>
<div class=""><br class="">
</div>
<div class="">//...</div>
<div class=""><br class="">
</div>
<div class="">for thing in
things {</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>if
let foo = thing as? Foo {
// needs an explicit cast</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>foo.bar()
// type checked, verified
by compiler, won’t crash
due to missing method</div>
<div class=""> }</div>
<div class="">}</div>
<div class=""><br class="">
</div>
<div class=""><br class="">
</div>
<div class="">One ancillary
benefit that I can see of
doing this is that it
could make AnyObject
consistent across darwin
and other platforms. As
far as I can tell, this
behavior only exists on
platforms where swift
integrates with the
objective-c runtime, and
doing this will help swift
code be more portable as
it doesn’t rely on this
implicit behavior.</div>
<div class=""><br class="">
</div>
<div class="">Any thoughts?</div>
<div class=""><br class="">
</div>
<div class="">--<br class="">
<div class="">
<div class="">Kevin
Lundberg</div>
<div class=""><a
moz-do-not-send="true"
href="mailto:kevin@klundberg.com" class=""><a class="moz-txt-link-abbreviated" href="mailto:kevin@klundberg.com">kevin@klundberg.com</a></a></div>
<div class=""><br
class="">
</div>
<br
class="Apple-interchange-newline">
</div>
<br class="">
</div>
</div>
</div>
</div>
_______________________________________________<br class="">
swift-evolution mailing list<br
class="">
<a moz-do-not-send="true"
href="mailto:swift-evolution@swift.org"
class="">swift-evolution@swift.org</a><br
class="">
<a moz-do-not-send="true"
href="https://lists.swift.org/mailman/listinfo/swift-evolution"
class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br
class="">
</div>
</blockquote>
</div>
<br class="">
</div>
</div>
</blockquote>
</div>
<br class="">
</div>
</div>
</blockquote>
</div>
<br class="">
</div>
</div>
_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a moz-do-not-send="true"
href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br
class="">
<a class="moz-txt-link-freetext" href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br
class="">
</div>
</blockquote>
</div>
<br class="">
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
swift-evolution mailing list
<a class="moz-txt-link-abbreviated" href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>
<a class="moz-txt-link-freetext" href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a>
</pre>
</blockquote>
<br>
</body>
</html>