tonisuter
(Toni Suter)
1
Hi
I am trying to use Swift in a Jupyter Notebook with the following Kernel: GitHub - rayh/iSwift: A Swift kernel for IPython.. This kernel seems to use the Swift REPL to evaluate the user's code. That works well in some cases, but there are a few problems. For example, consider the following example:
struct S: Equatable {
static func ==(lhs: S, rhs: S) -> Bool {
return false
}
}
If this code is evaluated in a REPL more than one time, it fails with the following error:
error: 'S' is ambiguous for type lookup in this context
So it seems like there are now multiple versions of the type S. In a Jupyter Notebook it is very common that a cell is executed multiple times.
Is there some way to "clear the history" of the REPL without restarting it? Or is there a better solution?
You could use a do statement, for local types and functions:
do {
struct S: Equatable {
static func ==(lhs: S, rhs: S) -> Bool {
return false
}
}
}
1 Like
tonisuter
(Toni Suter)
3
Thanks for your response! I think that could be a possible solution. My Jupyter notebook contains Swift exercises that consist of multiple steps each of which is displayed in a separate cell. If I wrap each cell in a do {} block, I can't access variables / functions / types that were declared in a previous cell. But maybe I just have to use one larger cell for each exercise that contains all the steps for that exercise. With the do {} block I could then at least execute the cell multiple times.
Another issue that I see with this approach is that some things (e.g., extensions, imports, operator declarations) need to be declared at file scope. But I can probably avoid those features in my use case.
tonisuter
(Toni Suter)
4
Here's another issue:
do {
struct S {
var x: Int
static func +(lhs: S, rhs: S) -> S {
return S(x: lhs.x + rhs.x)
}
}
let s1 = S(x: 1)
let s2 = S(x: 2)
print(s1 + s2) // error: binary operator '+' cannot be applied to two 'S' operands
}
When you overload an operator for a local type the compiler can't find the corresponding operator function. Seems like the == operator only works because of the Equatable auto-synthesis:
do {
struct S: Equatable {
static func ==(lhs: S, rhs: S) -> Bool {
return false
}
}
print(S() == S()) // true (but should be false)
}
I filed a bug here: [SR-8872] Operators for local types not working · Issue #51378 · apple/swift · GitHub