Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-10 Thread Joe DeCapo via swift-evolution

> On Dec 10, 2017, at 8:00 AM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
> None of which are true of ordinary protocols. Since then, we have added:
> 
> 5. Can only be conformed to in the main declaration.

This is the main thing that made me think Letanyan's suggestion of an attribute 
might make more sense for this than just a normal protocol. I'm not really a 
fan of bifurcating the semantics with an attribute denoting "safe"/"unsafe" 
versions of the protocol. But if this restriction is accepted (which I think it 
must be in order to avoid some legitimate concerns), this is something that 
would be unique to this protocol that no other protocol has had to adhere to. 
If this type of requirement isn't made available more generally to protocols, 
then this would be a very special case that complicates the definition of what 
a protocol is. I'm curious to hear Chris's thoughts on Paul's feedback.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-07 Thread Joe DeCapo via swift-evolution

> On Dec 7, 2017, at 11:29 AM, Letanyan Arumugam  wrote:
> 
> I think a better approach would still be to try and get the author of the 
> type to make the right choice in the first place.

After rereading the post you linked to last night 
(https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20171204/042015.html
 
),
 I think it could quickly get out of hand. It might be simple enough for 
DynamicMemberLookup, but once we get to the point of discussing DynamicCallable 
there are many more variations.

- Calls that return Void
- Calls that return an optional
- Calls that return an IUO
- Calls that throw
- etc.

I know this is a discussion about DynamicMemberLookup, but DynamicCallable is 
closely related and I imagine will end up following a similar pattern. How 
would you propose that DynamicCallable would be annotated in this fashion? 
There are a number of types of calls, and some are orthogonal so the 
combinations quickly add up. People will probably have similar concerns about 
failed call lookups as they do about member lookups.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-07 Thread Joe DeCapo via swift-evolution

> On Dec 7, 2017, at 10:41 AM, Letanyan Arumugam  wrote:
> 
> I think warning and error messages would be too much. I’m not concerned about 
> things being implemented in this way just as long as it’s appropriate. I 
> would think all language layers like Python should have trapping lookups and 
> calls.

To be clear, I meant a message that shows up in the console, not something like 
a warning in the IDE. Similar to messages about autolayout constraints being 
violated, or something of that nature.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-07 Thread Joe DeCapo via swift-evolution

> On Dec 7, 2017, at 10:12 AM, Letanyan Arumugam via swift-evolution 
>  wrote:
> 
> My original argument about failing for no discernible reason still stands. 
> precondition is a thought out check for a failing state. member lookup 
> failures are going to be because things don’t exist for which you presumably 
> expected to exist.

Is it necessarily true that things will have to fail "for no discernible 
reason"? It's up to the implementers of the protocol for how they want to 
handle the failure case (trap/return option/throw error/etc.). But I imagine it 
could be possible to add a generic debug error message/warning message about 
lookup failing for invocations of this kind, which would give a pretty clear 
hint about what went wrong and why. Would that be enough to address your 
concerns about silent failures?___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-07 Thread Joe DeCapo via swift-evolution

> On Dec 7, 2017, at 12:38 AM, Letanyan Arumugam via swift-evolution 
>  wrote:
> 
> My fear is that a design pattern around dynamic members and calls arise that 
> is used to bypass the perceived initial annoyance of Swifts type system from 
> new developers that come over to Swift and are now starting to try and go 
> native. They have no reason to think about their conforming types as 
> something that might fail because they’re using it to model behaviour that 
> they’re used to (good or bad). I don’t see why it’s so bad to remind people 
> that these conformances should be failing and only in rare cases should you 
> ever have a dynamic member lookup that is fine to ignore all failing lookups.
> 
> People coming from JavaScript could perceivably make dictionaries conform. 
> And later JSON, database, file and basically all resource API’s would follow.
> 
> Why would all of this happen rather than people behaving the way current 
> Swift community members behave?
> Because I worry that by bringing in people from other languages that a new 
> learning path is created. One where you start by learning your language 
> interoperating with Swift. And then pick up other Swift features as you go 
> along using your Python API for example. This would create a disparate Swift 
> community.

When I began writing Python, I initially named all my variables in camel case. 
And when I used the Subprocess module, I was passing return codes throughout my 
code base like it was bash. Even though I didn't know what was idiomatic in 
Python at that time, I could still sense a code smell in what I was writing. I 
soon learned that snake case was the standard, so I updated my code. And 
eventually I learned how to use exceptions and I refactored my code to use them 
instead of return codes. I doubt that this is unusual when coming to a new 
language with previous experience in other languages. It seems inevitable, and 
a normal process for becoming familiar with the idioms of a certain language 
community. I don't think we need to be so fearful of the community fracturing 
if people from a dynamic language background come to Swift and initially use 
those idioms. It will always be more burdensome to do things in a non-idiomatic 
way, and over time people will learn how to write idiomatic Swift.

Also, since this is an expert-level feature, I highly doubt that newcomers to 
Swift will be writing their own types that adopt the DynamicMemberLookup or 
DynamicCallable protocols. They'll simply be using existing bridges to the 
dynamic language they want to interact with. And if expert Swift users find a 
legitimate use case for this beyond dynamic language interop, I don't think 
that's necessarily a bad thing if it helps them solve their problem.

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-06 Thread Joe DeCapo via swift-evolution

> On Dec 6, 2017, at 9:45 PM, Paul Cantrell  wrote:
> 
> This seems marginally tolerable, but excessive.
> 
> Do we mark every usage of a type that can generate precondition failures or 
> fatal errors for reasons other than “no such method?” No, we don’t.
> 
> Do we use a syntactically privileged marker instead of just using words like 
> “unsafe” for types that expose direct access to raw memory? No, we don’t.
> 
> Has all of this ruined the language thus far? No. Because the Swift core team 
> doesn’t design, and the Swift community doesn’t adopt, ill-designed APIs that 
> turn these facts into problems.


Yeah, I think I'd prefer this to stay as a normal protocol conformance. But if 
the proportion of resistance is high enough, I think the adoption of some 
annotation above and beyond the norm would be ok (again, at the declaration 
site, not the call site). Especially since this is a somewhat privileged 
protocol if any of the restrictions suggested in the proposal go forward, since 
they don't really apply to normal protocols.

> My main objection to the critical responses is that most of the objections 
> are fundamentally cultural, not technical, and are fear-based, not 
> evidence-based.
> 
> If a little extra language ceremony helps assuage those fears, I guess I’d 
> consider it. I still think static analysis — starting and mostly ending with 
> boring old syntax coloring — answers most all the concerns people have 
> raised, and this debate is a tempest in a teapot.

I agree wholeheartedly. I was just trying to bring some specifics to the 
examples given so far.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-06 Thread Joe DeCapo via swift-evolution

> On Dec 6, 2017, at 5:46 PM, Letanyan Arumugam  wrote:
> 
> But IUO’s are marked with an “!” to differentiate it from a normal type, 
> where as DynamicMemberLookup is just a normal protocol conformance. I would 
> be curious as to what you think of this idea [1]? Would this still be too 
> much of a constraint just to make sure that when people use this they’re 
> explicitly aware of what they’re doing?

I think that sort of approach seems like an acceptable middle ground. There's 
probably some bike-shedding to be done about the terminology and such. I just 
think it's overboard to require explicit annotations at the call site 
(especially for every single call site invocation). I would totally be fine 
with some sort of extra annotation at the declaration site beyond a normal 
protocol conformance. I do think this jibes well with C#'s `dynamic` approach 
from what I've gathered so far, and which other people seem to think is a 
worthy standard we should look toward for inspiration.

My main objection to many of the critical responses to the proposal is that the 
examples all seem to ignore where the variables that are being invoked come 
from. I think we all tend to have a pretty good idea of what types we're 
dealing with, and what their behaviors are. And when we run into issues, we 
inspect those types. If this makes it more apparent on inspection that it has 
some special behavior, then I'm all for that. It would be similar to inspecting 
a type that crashed which turned out to be an IUO.

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-06 Thread Joe DeCapo via swift-evolution

> On Dec 6, 2017, at 12:39 PM, Thorsten Seitz via swift-evolution 
>  wrote:
> 
> IUO is Swift’s equivalent to a null pointer and those are a _hole_ in the 
> type system (this applies to all type systems having an equivalent to the 
> null pointer). That is why such types are marked with "!“ in Swift.
> This does not mean that Swift has no type system but that it’s type system 
> has carefully marked holes.

But the types are only marked with "!" at the declaration site, just as types 
conforming to DynamicMemberLookup and DynamicCallable would be marked at the 
declaration site. There's no more indication at the call site that something is 
an IUO than there would be for something conforming to these protocols. They 
both require inspecting the type itself.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-06 Thread Joe DeCapo via swift-evolution

> On Dec 6, 2017, at 7:41 AM, Vincent Esche via swift-evolution 
>  wrote:
> 
> If Swift had a rock-solid Generics system at this point and plenty of support 
> for Meta-Programming via hygienic example-based or procedural macros and/or 
> compiler plugins, then I'd be way less concerned about this feature getting 
> misused.
> 
> Alas while Swift's generics provide a nice basic foundation, they still have 
> big gaps in what can be expressed through them.
> And i'm not talking about HKT or any such more advanced use of types). I'm 
> talking about the basic stuff. Generic abstractions over type conversion. 
> Generic abstractions over arithmetic operators. This kind of stuff. Stuff, 
> that ironically would be necessary for a generic yet idiomatic implementation 
> of Linear Algebra algorithms in Swift.
> 
> I would prefer to get these gaps filled up before providing an orthogonal 
> feature that can easily be misinterpreted as a solution to the deficits in 
> Swift's generics system by someone coming from a dynamic language and/or 
> doesn't fully understand the use of generics.
> 
> We'd in essence be providing what looks like a solution in a time where 
> thousands of people are looking for workarounds to the limited expressiveness 
> of Swift's type system. That's like handing out bottles of Methanol for its 
> use as a household item in a time of severe drought. What could possibly go 
> wrong?

I think a more appropriate analogy would be to tools, rather than a toxic 
chemical during times of drought (I would hope the DynamicMemberLookup or 
DynamicCallable protocols won't result in any fatalities ;). Granted, I only 
have minimal woodworking experience so some details may be off. Let's say 
someone only has a hacksaw and circular saw. They're going to have to use these 
to do jobs that they shouldn't because they have no other option. Now, if 
someone is thinking about getting them a jigsaw, but says, "Well, they might 
use this jigsaw for things that a bandsaw or table saw would be more 
appropriate for, so let's wait until they get a bandsaw and table saw before 
giving them a jigsaw." Now they're still using inappropriate tools for the 
cases that a jigsaw would be suitable for. It would make more sense to give 
them the jigsaw to broaden the appropriate toolset, and then once they get the 
bandsaw and table saw they'll immediately stop using the jigsaw for those 
situations.

To me, the nastiest thing about the Swift standard library's internal 
implementation are gyb files. Admittedly, these solve a far more onerous 
problem than what this proposal is solving, but they're still a pretty ugly 
solution that come with problems of their own. But the people most excited and 
motivated to replace these with the appropriate solutions are the ones that 
wrote them or have to work with them 
(https://twitter.com/AirspeedSwift/status/936289022766333952). If people do end 
up using this as a workaround for some missing generics or type system feature, 
I imagine they would be the first to enthusiastically adopt the appropriate 
tools once they're available. And the great thing about software is that we can 
go back and actually change the tools we use to solve the same problem.

> It's also a completely different situation than what (from my understanding) 
> C# was in when they added `dynamic`.

I think this relates to a previous message I sent: 
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20171204/042018.html
 


Even with all the generic and reflective features in C# at the time, that 
author found it useful for simplifying code that didn't have anything to do 
with dynamic language support.


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-05 Thread Joe DeCapo via swift-evolution

> On Dec 5, 2017, at 1:13 PM, Thorsten Seitz via swift-evolution 
>  wrote:
> 
> let result = dynamic x.foo.bar  // will crash if foo or bar are not present
> 
> let result = dynamic? x.foo.bar // will return nil if foo or bar are not 
> present
> 
> // will crash if foo or bar are not present
> let result = dynamic {
>   let y = x.foo.bar
>   let z = y.baz(42)
>   return z.zork()
> }
> 
> // will return nil if foo or bar are not present
> let result = dynamic? {
>   let y = x.foo.bar
>   let z = y.baz(42)
>   return z.zork()
> } 

As other people have pointed out, the behavior of something conforming to these 
protocols in no way implies that they crash if lookup fails. That is up to the 
implementer, and I assume most, if not all, will choose sane defaults 
(optional/throws) rather than just crashing.

But I think the main thing missing from this is where `x` came from. As I think 
Chris pointed out before, these values have to come from somewhere. If you have 
no idea what the type of the variable you're dealing with is and what its 
intended behavior might be, then I don't understand how you could even write 
this code in the first place.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-05 Thread Joe DeCapo via swift-evolution

> On Dec 5, 2017, at 5:47 AM, Benjamin G  wrote:
> 
> About C#, in which i did program a few years ago (but before dynamic was in 
> the language), it already had powerful metaprogramming and introspection 
> capabilities, as well as very convenient  generics and interfaces ( easier to 
> work with than what swift offers today, but that was a long time ago so my 
> memory may be wrong). So, in some way, the potential for abusing dynamic or 
> "stringly typed" programming was a lot lower.

I find this perspective interesting because one of the articles I linked to on 
`dynamic` explicitly pointed out how it made some code far clearer than using 
reflection.

https://www.codeproject.com/Articles/69407/The-Dynamic-Keyword-in-C

The example code using reflection:
public class ReflectiveTester : Tester
{

static void WritePropertyReflectively(object instance, string propertyName)
{
Type type = instance.GetType();
PropertyInfo propertyInfo = type.GetProperty(propertyName);
if (propertyInfo == null)
Console.WriteLine("Property \"{0}\" not found, propertyInfo " + 
  "is null\r\npropertyInfo.GetValue(...) will 
result " + 
  "in a NullReferenceException", propertyName);
else
Console.WriteLine(propertyInfo.GetValue(instance, null));
}

static void CallMethodReflectively(object instance, string methodName)
{
Type type = instance.GetType();
MethodInfo methodInfo = type.GetMethod(methodName);
if (methodInfo == null)
Console.WriteLine("Method \"{0}\" not found, " + 
  "methodInfo set to null\r\nmethodInfo.Invoke(...) 
" + 
  "will result in a NullReferenceException", 
methodName);
else
methodInfo.Invoke(instance, null);
}

static void WriteClassDetails(object instance)
{
Type type = instance.GetType();
WritePropertyReflectively(instance, "Property");
CallMethodReflectively(instance, "Method");
}
}

The example code using `dynamic`:
public class DynamicTester : Tester
{
void WriteClassDetails(dynamic instance)
{
try
{
   Console.WriteLine(instance.Property);
   instance.Method();
}
catch (RuntimeBinderException ex)
{
ErrorWriters.WriteRuntimeBinderException(ex);
}
}
}
And a quote from the article:
> One thing to conclude on is that this is not less "OO" than the reflective 
> call; it is directly equivalent, but it has a neat syntax and less obtuse 
> exception mechanism. If viewed this way, the addition of dynamicis a large 
> benefit, even before the dynamic language support is considered.


As I've said, I'm as far from a C# expert as they come, but the C# devs seem to 
really appreciate this feature and it doesn't appear to have been abused in the 
way people here seem to fear for the proposed protocols.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-05 Thread Joe DeCapo via swift-evolution

> On Dec 4, 2017, at 11:24 PM, C. Keith Ray  wrote:
> 
> Not everyone uses the IDE as a crutch for writing code. As someone who has 
> used many languages, editors, and operating systems, I don't rely on 
> autocomplete and sometimes turn it off because it gets in my way.
> 
> my experience with C# was sometimes frustrating because it could be hard to 
> find the return type of a function, or the type of a "var" variable. Xcode's 
> playgrounds, faster search, and "print(type(of:x))" provides a nicer 
> experience.
> 
> (you should try Resharper and C# to see what refactoring support should look 
> like.)

Yeah, my main point was that things like autocompletion shouldn't really be a 
huge issue for this proposal. Even if we could match the state of the art in 
Python, it still would be inferior to the state of the art in Swift.

I've heard lots of good things about C# and the tooling around it, but being 
primarily a Mac user I've yet to find time to spend on a project in it. I 
definitely wouldn't be against trying it out some day :)___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-04 Thread Joe DeCapo via swift-evolution
> On Dec 4, 2017, at 9:30 PM, Chris Lattner  > wrote:
> 
> I personally am far more interested in getting to the bottom of Doug’s 
> concerns - it isn’t clear to me what exactly his preferred direction actually 
> is, but that discussion is based on engineering tradeoffs and may well lead 
> to a change to the proposal or a complete change in direction.
> 
> -Chris

Some notes on one of Doug's points:

> * Indexing/jump-to-definition/lookup documentation/generated interface won’t 
> ever work. None of the IDE features supported by SourceKit will work, which 
> will be a significant regression for users coming from a Python-capable IDE.

Here's the state of the art in PyCharm in a personal Python project (no type 
hints, but full comprehensive doc comments):

https://www.dropbox.com/s/ob54qalshf6gqth/Screenshot%202017-12-04%2022.11.22.png?dl=0
 


https://www.dropbox.com/s/drw6991u512g456/Screenshot%202017-12-04%2022.11.47.png?dl=0
 


https://www.dropbox.com/s/h8wuy91r1hfnsvj/Screenshot%202017-12-04%2022.12.05.png?dl=0
 


PyCharm is able to get the trivial cases right, but any of the more complex 
cases tend to end up looking something like that. I don't see any way that 
Swift could improve on that, and it's still a foreign experience to anyone used 
to developing Swift code in Xcode.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-04 Thread Joe DeCapo via swift-evolution

> On Dec 4, 2017, at 7:22 PM, Joe DeCapo via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
>> The first one, has no static type info, no compile time checking, it's not 
>> self documenting, no type inference so people will be forced to use a 
>> dynamic reference at the call site to store the result, leading to more type 
>> loss, and all this spirals down.
> 
> From what I can gather, `dynamic` is used when declaring types, but there's 
> no indication at call sites that what is being invoked is dynamic.

Upon rereading, I had assumed one could use `var` at the call site, but that 
may not be true. Even so, at the most there's still only one call site 
reference required, not for every following call site invocation.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-04 Thread Joe DeCapo via swift-evolution
I'm curious to get some feedback on this from people who would prefer a marker 
at every call site where a `DynamicMemberLookup` or `DynamicCallable` type is 
used. I haven't done any C# development before, but I read a few articles on 
the usage of `dynamic` and `var` in the language. I found it interesting that 
there are a number of posts cautioning against the use of `var` in C# for type 
inference, in preference to explicitly specifying types.

https://www.brad-smith.info/blog/archives/336
https://www.intertech.com/Blog/the-use-and-abuse-of-the-c-var-keyword/
https://weblogs.asp.net/stevewellens/can-the-c-var-keyword-be-misused
https://blogs.msdn.microsoft.com/ericlippert/2011/04/20/uses-and-misuses-of-implicit-typing/

It's almost comical to read those from the vantage point of a Swift developer, 
given that we tend to avoid explicit typing in every scenario we can, save for 
those where it's required. And I think most would agree that we've suffered no 
real problems due to it.

C# 3.0 introduced the `var` keyword in 2007. In 2010, C# 4.0 introduced the 
`dynamic` keyword. Here are a couple of quotes from devs about the `dynamic` 
keyword:

https://www.codeproject.com/Articles/69407/The-Dynamic-Keyword-in-C

> Earlier, I said that my initial reaction was negative, so what changed my 
> mind? To quote Margret Attwood, context is all.

https://stackoverflow.com/a/245537

> The first one, has no static type info, no compile time checking, it's not 
> self documenting, no type inference so people will be forced to use a dynamic 
> reference at the call site to store the result, leading to more type loss, 
> and all this spirals down.
> I'm already starting to fear dynamic.
> Edit: The danger has passed (Phew!) ... and dynamic wasn't been abused after 
> all, no need to down vote me after 3 years :)

From what I can gather, `dynamic` is used when declaring types, but there's no 
indication at call sites that what is being invoked is dynamic. And it even 
allows for casting basically anything to the `dynamic` type.

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/dynamic

So here we have a language community that was (is?) very vocal about caution 
when it comes to type inference with `var`, but seems to have accepted the 
validity of `dynamic`. This seems to show that at least one community has 
absorbed this sort of change (arguably a more "dangerous" version than what is 
being proposed here) with no real issues.

So I have a few questions:

- Would it be enough to require annotation of the dynamic nature of a type at 
the declaration sites, if that still means the call sites aren't explicitly 
annotated? 
- Is it really much different to require annotation with a keyword at type 
declaration sites, than to just inspect the type for conformance to 
`DynamicMemberLookup` and/or `DynamicCallable` (especially now that Chris added 
sections to the proposal forbidding retroactive conformance and the option of 
not allowing it as part of another protocol definition)? Admittedly it's one 
extra step of indirection when investigating an issue, but I assume we could 
have reasonable error messages nudging us toward the specific problem.
- Why do some think the Swift community would be more at risk of abuse of this 
feature than the C# community seems to have been? 

And if there's anyone with experience in C# where this was actually a 
legitimate issue, I would be happy to hear about your experience.

-Joe

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-04 Thread Joe DeCapo via swift-evolution

> On Dec 4, 2017, at 11:15 AM, Tino Heth <2...@gmx.de> wrote:
> 
>> 
>> This is a bridge to allow easy access to the vast number of libraries that 
>> currently exist in those dynamic language domains, and to ease the 
>> transition of the multitudes of those programmers into Swift.
> 
> I’ve read several posts that gave me the impression that Python has a huge 
> user base of people who are tired of using that language (the cited statement 
> is just an arbitrary pick)… but is that actually true?
> Afaik, Python never became as common as Java, C# or C++, and it never had 
> much support from big companies — people decided to use Python not because 
> it’s some sort of standard, but because they liked it and found it to be a 
> language that’s easy to learn.
> 
> So the whole story of „let’s make it easier for those poor Python guys to 
> switch to a real language“ sounds very much like hubris to me.
> Of course, that statement is an exaggeration, but still:
> Did anyone ever ask the Python-community who actually wants to switch to 
> Swift? I don’t think there would be enough positive feedback to take it as a 
> justification for the proposed changes.

That's not really what I meant, and I haven't gotten the impression that that's 
the main motivating reason. Partly it's for the benefit of the Swift community 
to leverage many currently existing, mature libraries that exist but are 
written in dynamic languages. And it makes it possible for someone interested 
in trying out Swift who has experience with those libraries to still be able to 
leverage the things they're already familiar with during the transition. There 
may not be an overwhelming number of developers who have to work in these 
languages but would prefer Swift, but I don't think there necessarily needs to 
be for this to still be a worthwhile change.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-04 Thread Joe DeCapo via swift-evolution

> On Dec 4, 2017, at 10:08 AM, Benjamin G via swift-evolution 
>  wrote:
> 
> 1_ From what i understood from this discussion (please correct me if i'm 
> wrong) python code is already callable from swift right now, without any 
> modification to the compiler, but then the syntax to *some* very generic 
> python function would just not be really pretty. If it's just library calls, 
> we could just wrap those calls into pretty functions for our needs, but then 
> : 

I think it's worthwhile to add this syntactic sugar to make wrapper libraries 
easier to write and reason about. From Chris's example playground:

let d = np.call(member: "array", args: Python.array(6, 7, 8),
kwargs: [("dtype", "i2")])
// Python:d = np.array([1, 2, 3], dtype="i2")
// Future Swift:  let d = np.array([6, 7, 8], dtype: "i2")

It's far easier (at least for me) to read the sugared Swift version and 
understand what it is doing than how it's currently required to be written.

I'm sure it's true that people coming from a background in a dynamic language 
will initially write "bad" Swift code. When I first started writing Python, I 
wrote it like Swift/Objective-C/Bash. But eventually I learned more of the 
common idioms in Python and rewrote my code to use those idioms. This is a 
bridge to allow easy access to the vast number of libraries that currently 
exist in those dynamic language domains, and to ease the transition of the 
multitudes of those programmers into Swift.

>From everything I've seen in the Swift community so far, I have faith that we 
>collectively won't abuse this feature to the point that it poisons what Swift 
>has achieved so far. And I'm not against some type of "guardrails" that help 
>prevent unintentional misuse, but I'd like for it not to be so much as to be 
>punishing to those that want to make use of the proposed features.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-03 Thread Joe DeCapo via swift-evolution

> On Dec 3, 2017, at 11:35 PM, Letanyan Arumugam via swift-evolution 
>  wrote:
> 
> I‘m not always the only one writing code (I could inherit a code base). I’ve 
> used languages with only dynamic lookup before and knowing about something 
> doesn’t always help especially when the documentation isn’t clear. Which is 
> very possible in this case were libraries could be made by third parties.

I find it very hard to believe that Swift libraries are going to end up 
exposing this as a public api en masse. And if you inherit a code base where 
it's used internally, then it's fully within your power to wrap these dynamic 
calls in more strongly typed wrappers (you could even do this with third party 
libraries if necessary). You could just as easily inherit a code base where 
force unwrapping or IUOs are used irresponsibly, but this doesn't mean that 
these language features have no legitimate use. The solution is to refactor the 
code to use these idioms in the correct way.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-03 Thread Joe DeCapo via swift-evolution
+1 to Paul's comments

Many of the concerns about typos causing runtime bugs scream out to me, "I want 
to write code that is completely untested and only validated by the compiler". 
But this is just as bad for a strong, statically typed language as it is for a 
weak, dynamically typed language (and honestly, in my experience, dynamic 
language communities seem to be way better about writing tests due to the fact 
that statically typed communities tend to rely way more on the compiler). At 
the very least, I would expect a programmer to run a happy path to make sure 
the code they wrote actually works. And if they don't, and it isn't then caught 
by QA, then there are much larger issues at hand than the language design. I'm 
not sure if people are concerned about the debug cycle or production issues due 
to these proposed changes. There's simply no way around the fact that writing 
code for a dynamic programming model is going to result in more time spent 
verifying, testing, and debugging runtime issues; no matter the amount of 
effort expended on gathering the maximal amount of type information available 
from the dynamic language, or the call site symbols the programmer is required 
to enter to get the code to compile.

> On Dec 3, 2017, at 8:06 PM, Paul Cantrell via swift-evolution 
>  wrote:
> 
> 
> 
>> On Dec 3, 2017, at 1:26 PM, Chris Lattner via swift-evolution 
>>  wrote:
>> 
>> On Dec 3, 2017, at 11:03 AM, Magnus Ahltorp  wrote:
>>> 
 4 Dec. 2017 02:40 Chris Lattner via swift-evolution 
  wrote:
 
 That’s a good principle.  However, a dynamic member lookup is just a 
 member lookup.  By that principle, it should look like a member lookup :-)
 
 Further, I incorporated some of the conversation with Matthew into the 
 proposal, showing how adding even a single sigil to dynamic member lookup 
 to distinguish it is problematic:
 https://gist.github.com/lattner/b016e1cf86c43732c8d82f90e5ae5438#increasing-visibility-of-dynamic-member-lookups
 
 Further, adding something like .dynamic would completely undermind the 
 proposal.  You can already write:
 
x.get(“foo”).get(“bar”)
 
 having to write:
 
x.dynamic.foo.dynamic.bar
 
 has no point.
>>> 
>>> This example shows what many on this list don't believe: that any Swift 
>>> method or member access can fail. If the return value of this "get" method 
>>> is an IUO, or not an Optional at all, and doesn't throw, then the 
>>> expression would have to fail hard if "foo" didn't resolve to something 
>>> meaningful.
>>> 
>>> The most common argument against this proposal is that someone could make 
>>> an API using Dynamic Member Lookup that could fail even though it is not 
>>> apparent to the caller. But, as we see in the example, this is just as 
>>> possible today.
>> 
>> Correct.  The argument also fails to recognize that (when bridging to a 
>> dynamic language):
>> 
>>  x+y
>> 
>> Is a completely dynamic method call which can fail (or return IUO), as is:
>> 
>>  x[i]
>> 
>> And that this is true with no changes to Swift.  The claim that such a thing 
>> is counter to the design of Swift is completely perplexing to me.
> 
> Chris, having myself nursed this sense that Swift is somehow “especially 
> safe” in a way that feels closer to ML than C, you’ve prompted me to consider 
> _why_ I feel that way.
> 
> Sentiments like this subjectively fit the _experience_ of using Swift. When 
> using the language in practice, it’s fairly clear to a mindful developer 
> which operations carry some inherent level of danger, what kind of danger 
> that is, how to reason about it, and how to mitigate it. (Usually, anyway.)
> 
> Having all had this pleasant experience, I think we may be too quick to look 
> for the explanation in the design of the language itself. We fail to notice 
> that it comes not from the language alone, but from the whole ecosystem that 
> surrounds it: standard library design, naming conventions, tools, libraries, 
> culture, Erica’s books, etc.
> 
> Optionals present themselves as a specially privileged part of the language; 
> `withUnsafeBytes` presents itself as a library call using existing language 
> features. But both share a similar definitively Swift-ish aesthetic in how 
> they guide our attention, and how they circumscribe programmer error while 
> leaving the language ergonomic and situationally adaptable.
> 
> Your reminder is a good one: Swift already does not have, and never has had, 
> a sense of safety that depends on Haskell-like strictness in the language 
> itself. The design question at hand in this thread thus becomes not “how can 
> we prevent dynamic dispatch from ruining everything” but rather “how can we 
> introduce this new element in a way that does not disrupt the ecosystem.” In 
> considering that, we’d do well to remember 

Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-03 Thread Joe DeCapo via swift-evolution

> On Dec 3, 2017, at 12:54 PM, Thorsten Seitz via swift-evolution 
>  wrote:
> 
> The difference is that IUOs are marked by a "!“ whereas dynamic member 
> lookups look just like normal member lookups but unlike them can fail.

We don't even need to bring up IUOs for it to be possible to write code that 
can fail without visibility at the call site. A contrived example:

func convertToInt(_ val: String) -> Int {
return Int(val)!
}

let val = "something"
// ... a bunch of code
let i = convertToInt(val) // Fatal error: Unexpectedly found nil while 
unwrapping an Optional value

This is trivially easy to do, and has been since Swift 1, but it's not 
something that has become a widespread issue.

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-03 Thread Joe DeCapo via swift-evolution
I like Chris's addition to the proposal about only allowing conformance on the 
original type definition, rather than requiring a class type.

https://gist.github.com/lattner/b016e1cf86c43732c8d82f90e5ae5438 


> In the discussion cycle, there was significant concern about abuse of this 
> feature, particularly if someone retroactively conforms a type to 
> DynamicMemberLookupProtocol. For this reason, the compiler only permits 
> conformance of this protocol on the original type definition, not extensions. 
> While the potential for abuse has never been a strong guiding principle for 
> Swift features (and many features can be abused, e.g. operator overloading, 
> emoji identifiers, AnyObject lookup, ImplicitlyUnwrappedOptional, and many 
> more) there is a strong argument that dynamic behavior is a core property of 
> a type that should be part of its declaration. If for some reason there 
> becomes a reason to relax this requirement, we can evaluate that as a 
> separate proposal based on its own merits. See the "Alternatives Considered" 
> section below for further ways to reduce potential for abuse.

It would be a shame if structs were excluded from these capabilities.

> On Dec 3, 2017, at 11:18 AM, Jose Cheyo Jimenez via swift-evolution 
>  wrote:
> 
> 
> 
> On Dec 3, 2017, at 8:41 AM, David Hart via swift-evolution 
> > wrote:
> 
>> 
>> 
>>> On 3 Dec 2017, at 04:11, Matthew Johnson via swift-evolution 
>>> > wrote:
>>> 
>>> 
>>> 
>>> Sent from my iPad
>>> 
>>> On Dec 2, 2017, at 7:40 PM, Chris Lattner >> > wrote:
>>> 
 On Dec 2, 2017, at 2:13 PM, Matthew Johnson > wrote:
>> For all those reasons, we really do need something like AnyObject 
>> dispatch if we care about working with dynamically typed languages.  The 
>> design I’m suggesting carefully cordons this off into its own struct 
>> type, so it doesn’t infect the rest of the type system, and is 
>> non-invasive in the compiler.
> 
> I am quite familiar with dynamic languages and agree that this is 
> necessary if we are going to fully open up access to these languages from 
> Swift.
 
 Ok, then it appears you agree that something like anyobject dispatch is 
 necessary for effective dynamic language interop.
 
>>> I strongly urge you to reconsider the decision of that dynamic members 
>>> must be made available with no indication at usage sites.  An 
>>> indication of dynamic lookup at usage sites aligns very well (IMO) with 
>>> the rest of Swift (AnyObject lookup aside) by calling attention to code 
>>> that requires extra care to get right.
>> 
>> I don’t understand this.  The proposal is fully type safe, and this 
>> approach is completely precedented by AnyObject.  Swift’s type system 
>> supports many ways to express fallibility, and keeping those decisions 
>> orthogonal to this proposal is the right thing to do, because it allows 
>> the author of the type to decide what model makes sense for them.
> 
> Allowing the author of the type to choose whether the mechanism is hidden 
> or visible is exactly what I don’t want to allow.  I think you have the 
> right design regarding types and semantics - the author chooses.  But I 
> don’t want these calls to look like ordinary member lookup when I’m 
> reading code.  
> 
> They inherently have a much greater chance of failure than ordinary 
> member lookup.  Further, authors are likely to choose immediate traps or 
> nil IUO as failure modes as forcing users to deal with Optional on every 
> call is likely to be untenable.  I believe this behavior should be 
> represented by some kind of syntax at the usage site.  I don’t believe it 
> is an undue burden.  It would make the dynamic lookup semantic clear to 
> all readers and would help to discourage abuse.
 
 I believe that adding explicit syntax would be counterproductive to your 
 goals, and would not make dynamic lookup syntax more clear.  I assume that 
 you would also want the same thing for DynamicCallable too, and operator 
 overloads, subscripts, and every other operation you perform on these 
 values, since they all have the exact same behavior.
 
 If we required some syntax even as minimal as “foo.^bar” and "baz^(42)”, 
 that change would turn this (which uses runtime failing or IUO return 
 values like AnyObject):
 
let np = Python.import("numpy")
let x = np.array([6, 7, 8])
let y =  np.arange(24).reshape(2, 3, 4)

let a = np.ones(3, dtype: np.int32)
let b = 

Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-03 Thread Joe DeCapo via swift-evolution
One common criticism people keep bringing up is that people will misuse this 
and end up exposing dynamic api's into general use (and without notation at the 
call site that draws attention to this, the user may accidentally invoke 
something dynamic they didn't intend to). I feel like there is enough prior art 
in current Swift libraries to disabuse us of this notion. Basically every 
library I've seen goes out of its way to provide a safe api and leverage 
Swift's strong type system in their public api's. We don't see libraries using 
force unwraps willy nilly to hide the fact that a non-optional return type is 
actually coming from an optional value, but this is something that has been 
possible since day one and is trivially easy to do.

There are essentially 2 "bad" use cases for consumers of these dynamic 
features: 1) as the consumer of a library that exposes these dynamic features 
as public api; and 2) as the creator of a library/executable that uses them 
irresponsibly internally. For (1) it's a very easy decision to simply not use a 
Swift library that exposes dynamic features like this externally if you object 
to it, and instead use an alternative. I highly doubt this would become 
idiomatic in the Swift community, because the enthusiasm for Swift is mostly 
based on the strong typing it provides. For (2) it is within the creator's 
complete control to refactor the code to work the preferred way. The moment 
there's an unintended invocation of a dynamic call, it can simply be wrapped in 
a more strongly typed Swift wrapper.

As for the autocompletion and jump-to-definition capabilities of the state of 
the art in Python, I've been working on a Python project for a few years and 
until recently only used Atom, which provided code completion with a plug-in, 
but I could have gotten by without it. I recently started using PyCharm, and 
although it has jump-to-definition capabilities, the dynamic nature of the 
language means that there's almost always multiple different possible matches, 
and most often the top choices are the wrong ones. I don't see how Swift could 
improve on this situation, and for the case of providing quick help, it may 
actively provide the wrong information. This is not to say that autocompletion 
and the like aren't worthwhile goals, but I don't think they're really an 
important barrier to initial adoption of a way to call into dynamic languages.

I get the sense that this is a minor syntactic sugar feature that would 
probably mostly be used by implementers of library wrappers to provide Swifty 
api's that call into dynamic language api's. So the concerns about 
autocompletion and pervasive exposure of these dynamic aspects more generally 
really feel misplaced. When writing a wrapper around a REST api, I get zero 
autocompletion when specifying the JSON models, but that in no way hampers my 
ability to wrap these api's. Sure, there may be more runtime bugs that I have 
to sort out when initially implementing things, but that's inherent in the 
nature of dealing with a dynamic programming model. I imagine it will be the 
same for Swift libraries wrapping dynamic language libraries.


> On Dec 3, 2017, at 10:41 AM, David Hart via swift-evolution 
>  wrote:
> 
> 
> 
>> On 3 Dec 2017, at 04:11, Matthew Johnson via swift-evolution 
>> > wrote:
>> 
>> 
>> 
>> Sent from my iPad
>> 
>> On Dec 2, 2017, at 7:40 PM, Chris Lattner > > wrote:
>> 
>>> On Dec 2, 2017, at 2:13 PM, Matthew Johnson >> > wrote:
> For all those reasons, we really do need something like AnyObject 
> dispatch if we care about working with dynamically typed languages.  The 
> design I’m suggesting carefully cordons this off into its own struct 
> type, so it doesn’t infect the rest of the type system, and is 
> non-invasive in the compiler.
 
 I am quite familiar with dynamic languages and agree that this is 
 necessary if we are going to fully open up access to these languages from 
 Swift.
>>> 
>>> Ok, then it appears you agree that something like anyobject dispatch is 
>>> necessary for effective dynamic language interop.
>>> 
>> I strongly urge you to reconsider the decision of that dynamic members 
>> must be made available with no indication at usage sites.  An indication 
>> of dynamic lookup at usage sites aligns very well (IMO) with the rest of 
>> Swift (AnyObject lookup aside) by calling attention to code that 
>> requires extra care to get right.
> 
> I don’t understand this.  The proposal is fully type safe, and this 
> approach is completely precedented by AnyObject.  Swift’s type system 
> supports many ways to express fallibility, and keeping those decisions 
> orthogonal to this proposal is the right thing to do, because it