On Nov 26, 2016, at 23:52, Robert Widmann <[email protected] 
<mailto:[email protected]>> wrote:

> Under the old behavior they must have identical declarations, that includes 
> precedence.  We specifically had to modify the precedences of some stuff in 
> Operadics to match Runes because of this and it worked just fine.
> 
>> On Nov 27, 2016, at 12:43 AM, David Sweeris <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>>> 
>>> On Nov 26, 2016, at 22:02, Dave Abrahams <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> 
>>> 
>>> on Sat Nov 26 2016, David Sweeris <davesweeris-AT-mac.com 
>>> <http://davesweeris-at-mac.com/>> wrote:
>>> 
>>>>> On Nov 26, 2016, at 17:19, Robert Widmann via swift-evolution 
>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>> 
>>>>> Just gotta field a version of that proposal that doesn’t “look like 
>>>>> Haskell” :)
>>>> Is there something wrong with Haskell's approach to imports? I don't
>>>> know how they do it, so I'm unaware of any pros/cons to their
>>>> approach. The ":)" makes me think I'm missing something...
>>>> 
>>>>> Seriously, though, would there be any objection to restoring the old
>>>>> behavior of just silently ignoring perfect duplicates of operator
>>>>> definitions across frameworks sans proposal?
>>>> Yeah, it could silently change how statements get evaluated, if I
>>>> start writing code using one library's operators, then import a 3rd
>>>> library which defines the same operators but with different
>>>> precedences. 
>>> 
>>> differnt precedences => not perfect duplicates, right?
>> 
>> That's a good question... I don't know... The compiler keeps track of 
>> functions by their "fully qualified" name, i.e. "MyLib.+(Int, Int)->Int", 
>> right? 
>> 
>> Swift's syntax only allows us to declare precedence on a per-operator basis. 
>> Does the compiler track precedence on a per-function basis anyway, and if 
>> so, how would you specify which precedence you want at the call site? Aside 
>> from parentheses, I mean.
>> 
>> - Dave Sweeris

I don't know what "operatics" or “runes” are. Based on the context I’d guess 
they’re two parts of the standard library, but I'd like to be sure.

Either way, though, I'm not sure this addresses my primary objection (which I 
wrote the wrong way around in my earlier email). Suppose a library does this:
//ALib
infix operator • : MultiplicationPrecedence
extension Double : IntegerArithmetic {...}
func • <T: IntegerArithmetic> (lhs: T, rhs: Array<T>) -> Array<T> { return 
rhs.map {lhs * $0} }
func + <T: IntegerArithmetic> (lhs: T, rhs: Array<T>) -> Array<T> { return 
rhs.map {lhs + $0} }
And another library does this, which is an easy copy/paste error to make, since 
everything still works as long as you only test single-operator expressions:
//ABuggedLib
infix operator • : AdditionPrecedence
//Some convenience functions for getting Ints into your Doubly goodness
func • (lhs: Int, rhs: Array<Double>) -> Array<Double> { return rhs.map 
{Double(lhs) * $0} }
func + (lhs: Int, rhs: Array<Double>) -> Array<Double> { return rhs.map 
{Double(lhs) + $0} }
You write your code like this:
//SomeFile.swift
import ALib
...
let x = 1 + 4 • [1.0, 2.0, 3.0] //[5, 9, 13]
Then six months later, for whatever reason — maybe it has some useful type or 
something — you decide that some other file needs to import ABuggedLib:
//SomeOtherFileInYourProject.swift
import ABuggedLib
...
//SomeFile.swift
import ALib
...
let x = 1 + 4 • [1.0, 2.0, 3.0] //silently changes to [5, 10, 15], even though 
neither this line, nor the file it’s in, have been touched in six months
The compiler won’t even give you an "ambiguous statement” error because the 
function in ABuggedLib takes an Int, which is a better match than the 
correctly-precedenced generic version in ALib. This “bug" might even be extra 
maddening, since I think it won’t actually show up until you either clean your 
project or touch “SomeFile.swift”… Potentially, there could be lot of time 
between cause (importing ABuggedLib) and effect (x’s value changing).

Dunno, maybe this isn't as big of an issue as I’m making it out to be... I 
don’t have any solutions for detecting when it happens, other than for IDEs to 
alert you whenever adding an import statement changes how code that’s already 
written would be compiled (this isn’t "Xcode-evolution", though, nor would it 
help people who use other editors).

I guess I’m really just arguing that operators and their precedences should be 
part of whatever name collision resolution scheme we come up with, and I don’t 
recall the old behavior doing that (I could be wrong there).

- Dave Sweeris



P.S. Relatedly, what’s the precedence of the dot product function here, anyway? 
If there’s a rule about “operators always take the highest precedence they can 
find” or something, I’m unaware of it.
import ALib //declares • with MultiplicationPrecedence
import ABuggedLib //declares • with AdditionPrecedence
//doesn’t need a operator declaration, since it’s already in an imported library
func • <T: IntegerArithmetic> (lhs: Array<T>, rhs: Array<T>) -> Array<T> {
    guard lhs.count == rhs.count else { fatalError("Dimension mis-match") }
    return (0 ..< lhs.count).map {lhs[$0] * rhs[$0]}
}
Or am I mistaken about not needing to provide my own operator declaration in 
this case?


_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to