> On Nov 20, 2017, at 7:47 PM, Chris Lattner via swift-evolution
> <[email protected]> wrote:
>
>> On Nov 20, 2017, at 1:41 PM, David Waite <[email protected]>
>> wrote:
>>
>> In ruby, parens are optional. So,
>>
>> v = foo.value
>>
>> and
>>
>> v = foo.value()
>>
>> are identical.
>
> Ok, I wasn’t aware of that. It isn’t clear that we’d want to carry that into
> a “Ruby APIs when used in Swift” though! One could definitely argue against
> the former calling a method, even if that is possible in Ruby APIs.
>
>> There dot syntax is only used for method invocation, so there is no external
>> access to instance variables without some twiddling; similarly getting
>> access to a Proc/lambda/Method requires twiddling in Ruby (although there
>> are shortcuts in normal use, like Symbol#to_proc)
>
> I think you’re missing the idea here: the idea isn’t to provide exactly
> syntax mapping of Ruby (or Python) into Swift, it is to expose the underlying
> semantic concepts in terms of Swift’s syntax. In the case of Python, there
> is a lot of direct overlap, but there is also some places where Swift and
> Python differs (e.g. Python slicing syntax vs Swift ranges). In my opinion,
> Swift syntax wins here, we shouldn’t try to ape a non-native syntax in Swift.
>
>> For mapping to Swift, I would say that parens are needed; we can’t guess
>> whether a `foo.bar` is meant to be asking for the value of attribute bar or
>> a reference to method bar.
>
> +1
Chris, did you follow at all the earlier chain of emails where Brent,
Jean-Daniel and I hashed this out at length? You may not have got to it yet….
Key excerpts:
–––––––––––––––––––––––––
An “always use parens” bridge to Ruby has bad ergonomics
Zero-arg Ruby methods are a mixture of property-like things that would
certainly not use parens in Swift, and function-like things that certainly
would:
// Idiomatic Swift:
post.author.name.reversed()
// Swift bridging to Ruby…
// …if no-args methods •must• use parens:
post.author().name().reverse()
// …if no-args methods •can’t• use parens:
post.author.name.reverse
If the goal is to make Swift mostly feel like Swift even when bridging to Ruby,
then the bridge needs to support both access forms.
–––––––––––––––––––––––––
Separating method calls from property accesses solves the problem
Brent wrote:
> If we had separate subscripts for methods and properties, then the property
> subscript could immediately call the appropriate getters and setters, while
> the method subscript could return a ready-to-call `Method` object.
Better yet, why bother with the ready-to-call Method-like object? Just call it!
A Ruby binding with separate property and method handling would then look like
this:
extension RubyObj: DynamicMemberLookupProtocol {
func callDynamicMethod(dynamicMethod method: String, args: [RubyObject])
-> RubyObj {
get {
return RubyObject_send(rubyObject, method: member, args: args)
}
}
subscript(dynamicMember member: String) -> RubyObj {
get {
return RubyObject_send(rubyObject, method: member, args: [])
}
set {
RubyObject_send(rubyObject, method: "\(member)=", args: [newValue])
}
}
}
When Swift sees myObj.name, it uses the getter subscript. When Swift sees
myObj.name(), it uses the method invocation. Both work in Swift just as they do
in Ruby — and more importantly, Ruby APIs wouldn’t feel so very awkward when
used from Swift.
>
>> More difficult would be the use of ‘=‘, ‘!’, and ‘?’ - all legal in Ruby
>> method names as suffixes.
>
> Using those would require backquotes:
>
> x.`what?`()
>
>
> -Chris
>
>
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution