What is the equivalent to `thing = this() || that` in Swift 3? - swift3

In most languages I can write something like this:
this = this() || that()
If this() returns something false, like integer 0, that() will be evaluated. Pretty common idiom.
Swift 3 doesn't automatically cast Int to Bool so that idiom doesn't work. What is a succinct way to do it in Swift 3?

There's no exact equivalent in Swift, as:
No other types than Bool cannot be converted to Bool
You cannot write a function returning Bool or Int
(In most languages is a little bit exaggerated, you cannot write such thing in Java, C# or many other strongly-typed languages.)
The most similar thing in Swift is nil-coalescing operator -- ??.
Assume this() returns Int? (aka Optional<Int>), and that() returns Int (non-Optional):
func this() -> Int? {
//...
if someCondition() {
return intValue
} else {
return nil
}
}
func that() -> Int {
//...
return anotherIntValue
}
And use nil-coalescing operator like this:
let result = this() ?? that()
In this assignment, if this() returns non-nil value, then that() is not evaluated, and that non-nil value is assigned to result. When this() returns nil, that() is evaluated and the value is assigned to result.

The nil coalescing operator as covered by #OOPer:s answer is the fit for purpose idiom here, but as a side-note, you could implement functionality as the one your describe by overloading the || operator, e.g. for types that conform to some type constraint. E.g. using Integer as type constraint:
extension Bool {
init<T : Integer>(_ value: T) {
self.init(value != 0)
}
}
func ||<T: Integer>(lhs: T, rhs: #autoclosure () -> T) -> T {
return Bool(lhs) ? lhs : rhs()
}
var thisNum = 0
let thatNum = 12
thisNum = thisNum || thatNum
print(thisNum) // 12

Related

Kotlin reduce has limitations?

I would like to implement the same following code, using the reduce method. I know this is possible in other languages, but I don't know how to achieve it in Kotlin
class A
class B (val a: A?)
fun test(listOfBs: List<B>): List<A> {
return listOfBs.filter { it.a != null }.map { it.a!! }
// TODO return listOfBs.reduce { ??? }
}
Instead of calling filter and then map, you can use mapNotNull from the Kotlin Standard Library. This function combines the two and you can avoid the Hold My Beer operator (!!).
Example:
fun test(listOfBs: List<B>): List<A> =
listOfBs.mapNotNull { it.a }
reduce in Kotlin is not suitable for this. It is declared like this:
inline fun <S, T : S> Iterable<T>.reduce(
operation: (acc: S, T) -> S
): S
Notice how it can only return an S, which is a super type of the element type T. This means that you can't reduce a List<B> to a List<A>.
In "other languages", you can specify an "identity element" when reducing, and you probably also want to do that. In Kotlin, you can do that with fold:
fun test(listOfBs: List<B>): List<A> =
listOfBs.fold(emptyList()) { acc, b ->
if (b.a != null) {
acc + listOf(b.a) // this is very bad code, it creates a bunch of unnecessary lists
} else {
acc
}
}
But of course, "mapping only if not null" is a common enough thing to do that it is already built into the Kotlin Standard Library - mapNotNull:
fun test(listOfBs: List<B>): List<A> =
listOfBs.mapNotNull { it.a }
You can have a look at how reduce is implemented in the Kotlin standard library:
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/reduce.html

What is concise way of deep-copying a 2D MutableList?

The element already implemented deep copying.
fun <T : DeepCopiable> f(a: MutableList<MutableList<T>>) {
val copied = a.map { it.map { it.deepCopy() }.toMutableList() }.toMutableList()
...
}
I am using this kind of code, but it seems verbose.
Due to restrictions in the type system, this problem cannot be generalized to a single functon without bypassing type safety (and due to JVM type erasure you definitely don't want to go that rabbit hole when generics are involved¹).
However, you can write a chain of extension functions implementing a deep-copy pattern, delegating to the previous function for every increase in dimension, in a type safe matter:
private typealias I<E> = Iterable<E>
private typealias Copy<E> = (E) -> E
private inline fun <T, R> I<T>.mapToMutable(transform: (T) -> R): I<R> = mapTo(mutableListOf(), transform)
fun <E> I<E>.deepCopy1(c: Copy<E>) = mapToMutable { c(it) }
fun <E> I<I<E>>.deepCopy2(c: Copy<E>) = mapToMutable { it.deepCopy1(c) }
fun <E> I<I<I<E>>>.deepCopy3(c: Copy<E>) = mapToMutable { it.deepCopy2(c) }
fun <E> I<I<I<I<E>>>>.deepCopy4(c: Copy<E>) = mapToMutable { it.deepCopy3(c) }
fun <E> I<I<I<I<I<E>>>>>.deepCopy5(c: Copy<E>) = mapToMutable { it.deepCopy4(c) }
Due to JVM type erasure, the functions need different names (#JVMName does not help due to type interference ambiguity²). Type aliases are used to prevent horizontal space explosion³, and the function set is uncoupled from the deep-copiable interface via a generic copy function parameter.
Example usage:
fun main(args: Array<String>) {
data class IntHolder(var value: Int)
val original = List(3) { a ->
List(3) { b ->
IntHolder(a + b)
}
}
val copied = original.deepCopy2 { it.copy() }
original[0][0].value = 18258125
println("original=$original")
println("copied =$copied")
}
->
original=[[IntHolder(value=18258125), IntHolder(value=1), IntHolder(value=2)], [IntHolder(value=1), IntHolder(value=2), IntHolder(value=3)], [IntHolder(value=2), IntHolder(value=3), IntHolder(value=4)]]
copied =[[IntHolder(value=0), IntHolder(value=1), IntHolder(value=2)], [IntHolder(value=1), IntHolder(value=2), IntHolder(value=3)], [IntHolder(value=2), IntHolder(value=3), IntHolder(value=4)]]
[1]: Because generic type casts are performed by the compiler at runtime, a cast from List<Foo> to List<Baz> will always succeed at runtime, but fail later upon access of the casted list. Implementing mentioned magic "single function" is possible, but the slightest of error would result in a returned data structure that fails seemingly "random" upon access with class cast exceptions.
[2]: A value of type Iterable<Iterable<Foo>> satisfies both
fun <T> Iterable<T>.baz() (T = Iterable<Foo>) and
fun <T> Iterable<Iterable<T>.baz() (T = Foo)
Due to this, the compiler would not be able to determine the right method to use if all methods in the chain have the same function name, but different JVM names.
[3]:
Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<ithinkyougetthepoint>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Here is a simple deep copy example by using java.lang.reflect.Array & java.lang.Cloneable.
Noet: the clone method performs a shallow copy of this object, not a deep copy operation, but you can override the clone method to provide a deep copy operation, for example:
val list = mutableListOf(mutableListOf(arrayOf(1)))
val copied = list.deepCopy()
println(copied !== list) //true: not the same
println(copied.map{it.map{it.toList()}} == list.map{it.map{it.toList()}})
// ^---true: content equals
// v--- Array is cloned, since it has implemented Cloneable
println(copied[0][0] !== array[0][0]) // true
typealias NativeArray = java.lang.reflect.Array
#Suppress("UNCHECKED_CAST")
fun <T> T.deepCopy(): T {
return when (this) {
is Array<*> -> {
val type = this.javaClass.componentType
NativeArray.newInstance(type, size).also {
this.forEachIndexed { i, item ->
NativeArray.set(it, i, item.deepCopy())
}
} as T
}
is MutableList<*> -> this.mapTo(mutableListOf()) { it.deepCopy() } as T
is List<*> -> this.map { it.deepCopy() } as T
is Cloneable -> this.javaClass.getDeclaredMethod("clone").let {
it.isAccessible = true;
it.invoke(this) as T
}
else -> this
}
}

Go - testing function equality

So from what I've read, you can't test if a function is equal in Go, but I'm trying to solve a test-case issue, so any help in refactoring this would be helpful.
I have a constructor and I'm passing it some configuration values. Based on those configs, it assigns another constructor function to a member of the struct. Later, in a different method, it calls that new constructor. I did it this way because it made it easier to test the methods on the struct, since I could now create a test constructor and reassign the struct member to it, before calling the methods I was testing. Similar to the approach here: Mock functions in Go
Now though, I'm trying to write a test case on the struct constructor and I'm having a hard time figuring out how to test it.
Here's an example:
type requestBuilder func(portFlipArgs, PortFlipConfig) portFlipRequest
type portFlip struct {
config PortFlipConfig
args portFlipArgs
builder requestBuilder
}
func newPortFlip(args portFlipArgs, config PortFlipConfig) (*portFlip, error) {
p := &portFlip{args: args, config: config}
if p.netType() == "sdn" {
p.builder = newSDNRequest
} else if p.netType() == "legacy" {
p.builder = newLegacyRequest
} else {
return nil, fmt.Errorf("Invalid or nil netType: %s", p.netType())
}
return p, nil
}
The 'newSDNRequest' and 'newLegacyRequest' are the new constructors. I can't figure out how to test the newPortFlip method to make sure that's it assigning the right method to the 'builder' member, since you can't test function equality.
My only thought at this point is to have a 'builderType string' member, and just assign it to the name of the new constructor and then I could just test that. Something like:
func newPortFlip(args portFlipArgs, config PortFlipConfig) (*portFlip, error) {
p := &portFlip{args: args, config: config}
if p.netType() == "sdn" {
p.builderType = "newSDNRequest"
p.builder = newSDNRequest
} else if p.netType() == "legacy" {
p.builderType = "newLegacyRequest"
p.builder = newLegacyRequest
} else {
return nil, fmt.Errorf("Invalid or nil netType: %s", p.netType())
}
return p, nil
}
But that seemed rather frivolous, so I figured I should seek a better way before I did that.
Thoughts?
Make portFlip an interface and have newPortFlip construct either an sdnPortFlip or a legacyPortFlip depending on the incoming type. In your test you can then check it's returning the correct concrete type using a type assertion.
If you embed the common type into the SDN and legacy types then you can directly call those methods.
type portFlip interface {
build()
...
}
type portFlipCommon struct {
config PortFlipConfig
args portFlipArgs
}
type portFlipSdn struct {
portFlipCommon
}
type portFlipLegacy struct {
portFlipCommon
}
func (pf *portFlipCommon) netType() { ... }
func (pf *portFlipSdn) build() { ... }
func (pf *portFlipLegacy) build() { ... }
func newPortFlip(args portFlipArgs, config PortFlipConfig) (portFlip, error) {
var pf portFlip
p := &portFlipCommon{args: args, config: config}
if p.netType() == "sdn" {
// Either build directly or define build on the sdn type
pf = &portFlipSdn{*p}
} else if p.netType() == "legacy" {
// Either build directly or define build on the legacy type
pf = &portFlipLegacy{*p}
} else {
return nil, fmt.Errorf("Invalid or nil netType: %s", p.netType())
}
return pf, nil
}

Swift: statically "append" to tuple type

I have a templated struct in a Swift library I am writing. This struct has two characteristics:
Every struct "wraps" or "represents" another arbitrary type. A Foo<T> wraps a T
These structs can be "combined" to form a third struct, whose represented type should be a "combination" (read: tuple) of the first two. In another worlds, if fooA: Foo<A> and fooB: Foo<B>, then fooA + fooB should be of type Foo<(A, B)>.
This works well enough when there are only two types to combine, but when you chain this combination operation you start getting nested tuples, which is not what I want. For example, in the following code:
let a = Foo<A>(/* initialize */)
let b = Foo<B>(/* initialize */)
let c = Foo<C>(/* initialize */)
let d = a + b // type is Foo<(A, B)>
let e = d + c // type is Foo<((A, B), C)>
d has type Foo<(A, B)>, which is what we want, but e has type Foo<((A, B), C)>, which is an extra level of unwanted nesting.
I need some way to express that the combination of a Foo<A> and a Foo<B> is not a Foo<(A, B)>, but rather a Foo<A + B>, where + is a hypothetical static operation which means "if the first type is a tuple type, append the second type onto it, yielding a new, non-nested tuple type. If it is not a tuple type, simply make the tuple type (A, B).
This feels like pushing to compiler to (beyond?) its limits, and I suspect that it might not be possible with Swift's current templating capabilities and type system. Still, if anyone can offer a workaround, a redesign that doesn't encounter this problem in the first place, or something conceptually similar but not identical to what I'm trying to do, it would be extremely helpful. As things stand, I'm at an impasse.
I think there is no generic way to do that.
Maybe, you can do something like this:
struct Foo<T> {
let v: T
init(_ v:T) { self.v = v }
}
func +<A,B>(lhs: Foo<(A)>, rhs:Foo<(B)>) -> Foo<(A,B)> { return Foo(lhs.v.0, rhs.v.0) }
func +<A,B,C>(lhs: Foo<(A,B)>, rhs: Foo<(C)>) -> Foo<(A,B,C)> { return Foo(lhs.v.0, lhs.v.1, rhs.v.0) }
func +<A,B,C>(lhs: Foo<(A)>, rhs: Foo<(B,C)>) -> Foo<(A,B,C)> { return Foo(lhs.v.0, rhs.v.0, rhs.v.1) }
func +<A,B,C,D>(lhs: Foo<(A,B,C)>, rhs: Foo<(D)>) -> Foo<(A,B,C,D)> { return Foo(lhs.v.0, lhs.v.1, lhs.v.2, rhs.v.0) }
func +<A,B,C,D>(lhs: Foo<(A,B)>, rhs: Foo<(C,D)>) -> Foo<(A,B,C,D)> { return Foo(lhs.v.0, lhs.v.1, rhs.v.0, rhs.v.1) }
func +<A,B,C,D>(lhs: Foo<(A)>, rhs: Foo<(B,C,D)>) -> Foo<(A,B,C,D)> { return Foo(lhs.v.0, rhs.v.0, rhs.v.1, rhs.v.2) }
// ... as many as you want ...
let f1 = Foo<(Int, UInt)>(1, 2) + Foo<String>("string") // -> as Foo<(Int, UInt, String)>

Build a function object with properties in TypeScript

I want to create a function object, which also has some properties held on it. For example in JavaScript I would do:
var f = function() { }
f.someValue = 3;
Now in TypeScript I can describe the type of this as:
var f: { (): any; someValue: number; };
However I can't actually build it, without requiring a cast. Such as:
var f: { (): any; someValue: number; } =
<{ (): any; someValue: number; }>(
function() { }
);
f.someValue = 3;
How would you build this without a cast?
Update: This answer was the best solution in earlier versions of TypeScript, but there are better options available in newer versions (see other answers).
The accepted answer works and might be required in some situations, but have the downside of providing no type safety for building up the object. This technique will at least throw a type error if you attempt to add an undefined property.
interface F { (): any; someValue: number; }
var f = <F>function () { }
f.someValue = 3
// type error
f.notDeclard = 3
This is easily achievable now (typescript 2.x) with Object.assign(target, source)
example:
The magic here is that Object.assign<T, U>(t: T, u: U) is typed to return the intersection T & U.
Enforcing that this resolves to a known interface is also straight-forward. For example:
interface Foo {
(a: number, b: string): string[];
foo: string;
}
let method: Foo = Object.assign(
(a: number, b: string) => { return a * a; },
{ foo: 10 }
);
which errors due to incompatible typing:
Error: foo:number not assignable to foo:string
Error: number not assignable to string[] (return type)
caveat: you may need to polyfill Object.assign if targeting older browsers.
TypeScript is designed to handle this case through declaration merging:
you may also be familiar with JavaScript practice of creating a function and then extending the function further by adding properties onto the function. TypeScript uses declaration merging to build up definitions like this in a type-safe way.
Declaration merging lets us say that something is both a function and a namespace (internal module):
function f() { }
namespace f {
export var someValue = 3;
}
This preserves typing and lets us write both f() and f.someValue. When writing a .d.ts file for existing JavaScript code, use declare:
declare function f(): void;
declare namespace f {
export var someValue: number;
}
Adding properties to functions is often a confusing or unexpected pattern in TypeScript, so try to avoid it, but it can be necessary when using or converting older JS code. This is one of the only times it would be appropriate to mix internal modules (namespaces) with external.
So if the requirement is to simply build and assign that function to "f" without a cast, here is a possible solution:
var f: { (): any; someValue: number; };
f = (() => {
var _f : any = function () { };
_f.someValue = 3;
return _f;
})();
Essentially, it uses a self executing function literal to "construct" an object that will match that signature before the assignment is done. The only weirdness is that the inner declaration of the function needs to be of type 'any', otherwise the compiler cries that you're assigning to a property which does not exist on the object yet.
EDIT: Simplified the code a bit.
Old question, but for versions of TypeScript starting with 3.1, you can simply do the property assignment as you would in plain JS, as long as you use a function declaration or the const keyword for your variable:
function f () {}
f.someValue = 3; // fine
const g = function () {};
g.someValue = 3; // also fine
var h = function () {};
h.someValue = 3; // Error: "Property 'someValue' does not exist on type '() => void'"
Reference and online example.
As a shortcut, you can dynamically assign the object value using the ['property'] accessor:
var f = function() { }
f['someValue'] = 3;
This bypasses the type checking. However, it is pretty safe because you have to intentionally access the property the same way:
var val = f.someValue; // This won't work
var val = f['someValue']; // Yeah, I meant to do that
However, if you really want the type checking for the property value, this won't work.
I can't say that it's very straightforward but it's definitely possible:
interface Optional {
<T>(value?: T): OptionalMonad<T>;
empty(): OptionalMonad<any>;
}
const Optional = (<T>(value?: T) => OptionalCreator(value)) as Optional;
Optional.empty = () => OptionalCreator();
if you got curious this is from a gist of mine with the TypeScript/JavaScript version of Optional
An updated answer: since the addition of intersection types via &, it is possible to "merge" two inferred types on the fly.
Here's a general helper that reads the properties of some object from and copies them over an object onto. It returns the same object onto but with a new type that includes both sets of properties, so correctly describing the runtime behaviour:
function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
Object.keys(from).forEach(key => onto[key] = from[key]);
return onto as T1 & T2;
}
This low-level helper does still perform a type-assertion, but it is type-safe by design. With this helper in place, we have an operator that we can use to solve the OP's problem with full type safety:
interface Foo {
(message: string): void;
bar(count: number): void;
}
const foo: Foo = merge(
(message: string) => console.log(`message is ${message}`), {
bar(count: number) {
console.log(`bar was passed ${count}`)
}
}
);
Click here to try it out in the TypeScript Playground. Note that we have constrained foo to be of type Foo, so the result of merge has to be a complete Foo. So if you rename bar to bad then you get a type error.
NB There is still one type hole here, however. TypeScript doesn't provide a way to constrain a type parameter to be "not a function". So you could get confused and pass your function as the second argument to merge, and that wouldn't work. So until this can be declared, we have to catch it at runtime:
function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
if (typeof from !== "object" || from instanceof Array) {
throw new Error("merge: 'from' must be an ordinary object");
}
Object.keys(from).forEach(key => onto[key] = from[key]);
return onto as T1 & T2;
}
This departs from strong typing, but you can do
var f: any = function() { }
f.someValue = 3;
if you are trying to get around oppressive strong typing like I was when I found this question. Sadly this is a case TypeScript fails on perfectly valid JavaScript so you have to you tell TypeScript to back off.
"You JavaScript is perfectly valid TypeScript" evaluates to false. (Note: using 0.95)