Submodules in Swift - swift

Say I have an app, MyApp which is built in an Xcode workspace. Inside this workspace I have the primary app target and two nested Xcode projects for my frameworks, Foo and Bar.
Inside my app I import Foo and Bar and dependency inject an object in Foo into an object in Bar. Say, however, I don't need all of Foo, just a couple of classes. How could I create a submodule within foo and import that. E.g. import Foo.Models.Animals.Dog

While you can do something like
import struct MyModule.MyStruct
import func Darwin.glob
I'm not sure if you can get much deeper than that. Here's a relevant quote from the (free) Swift book
“Providing more detail limits which symbols are imported—you can specify a specific submodule or a specific declaration within a module or submodule. When this detailed form is used, only the imported symbol (and not the module that declares it) is made available in the current scope.”
It goes on to explain that you can import any of typealias, struct, class, enum, protocol, var, or func
It looks as though Swift has some type of support for submodules (they're mentioned offhand a few places), but I'm not sure we have the ability to actually compile those just yet.

Related

How can I disambiguate my type from a module type

I am having troubles referring to a symbol from 3rd party module, my code looks something like this:
import Foo // 3rd party module
struct Foo { // my type on my module
//...
}
struct Bar: Foo.ProtocolA { // here swift referes to my struct instead of the module
}
I cannot only use : ProtocolA because that name is already being used in my module.
Is there a way to disambiguate this?
I have seen similar questions but they solve different thing, disambiguating a module type instead of own type.
TIA
You can fix this by importing the submodules from the parent module directly; e.g. in your example that would become something like:
import protocol Foo.ProtocolA
You can specify many types to import, like class enum let/var etc. as well, not only a protocol.
The obvious downside is that the amount of imports can balloon quickly if you need a lot of submodules from the specific parent module.
Personally I usually try to avoid naming collisions altogether, sometimes at the expensive of slightly less descriptive naming while still being understandable. Additionally as far as I know there is no way to alias imports at this time in Swift.

Where to put my Struct to keep classes independent?

I have a class which I want to be reusable (for any developer user who wants it, or outside my project). This class returns a Struct lets call it structA, and the class is classA.
The first thought is to put structA inside the same file of this class, so while the Struct is public, any user who get this class file can read this Struct which the class returns.
Till here it looks reasonable. (or not)
But what happens if other classes in my current project also need to use this Struct for other purposes? (a copy of it)
Then to make the code reusable I need to put this struct somewhere else.
By reusable I mean there are no dependencies- get the class file and that is it.
If it's outside classA, then classA becomes not reusable and dependent.
If it's inside classA, then other class that use it are also dependent(not reusable outside)
The only solution left is to create other Structs like this with different names(sounds bad)
Where would you put this Struct in your Xcode project?
Put your struct in a separate file and document for each class you want to reuse that it depends on this struct. So basically you make your struct reusable as well.
The process of reusing your class becomes a little bit harder - you also have to include it’s dependencies. But that is just a fact of life, basically all software has dependencies. To make it easier to add some code dependency manages such as Cocoapods, Carthage or the Swift Package Manager have been invented. With those you specify for each library what it depends on - so ClassA depends on StructA. In the project you want to use ClassA you specify only that dependency and the package manager installs all of it’s dependencies (and their dependencies and so on) together.
You can create a separate library or framework which will contain all the reusable classes and structs.
Whenever you want to use the class classA or the struct structA, you can just import that library in the respective file.
Repeating the code is not recommended.

Access class in different file

I'm still a newbie to swift and I can't get a clear answer on a couple things.
So far I've just been using a single file in playgrounds.
If I want to use more files, how can I access data (variables and functions) from classes created there in my main file that controls the view?
From what I understand having multiple files would just be for convenience so I don't have could to write it again.
(Also on the side) what does it mean when a function has private, public or just 'func'?
I'm using swift 3 playgrounds
Thanks
Making things public will make them importable from other modules. Making it private will make it only accessible by methods within its containing scope (encapsulation). For code that lives at the top level, this scope is the entire .swift file it lives in. Without either access modifier (just bare “func”), your thing will default to internal, which means it is accessible from any other code within the same module, but not by code in a different module.
A special case is the fileprivate modifier which restricts access to the .swift file the code lives in. For code that does not live in a class or struct, this does the exact same thing as private. Some Swift designers discourage use of this modifier, and it may be removed in future versions of Swift.
There is a fifth access modifier in Swift, open, which does the exact same thing as public, except it also allows subclassing, and only applies to classes. This one is rarely used, but useful for certain library interfaces.
To import all the public symbols in a module, use
import Module
To import a single public symbol, use
import var Module.variable
import func Module.function
import struct Module.structure
import class Module.class
...

Why doesn't this default java import work?

I'm learning java and I'm told this package is provided by default, to every class, because its methods are so common. I thought I would try to import it, any way to see what would happen. I know its not practical and probably expensive but I'm curious as to why it's doesn't work from a technical point of view.
import javax.lang.*;//why doesn't this work.
javax.lang contains only a single package: model
https://docs.oracle.com/javase/7/docs/api/index.html?javax/lang/model/package-summary.html
you're not doing anything by importing this package. Maybe you're confusing it with java.lang ?
You don't need to import java.lang.*
There is one exception to the import rule. All classes in the java.lang package are imported by default. Thus you do not need to import java.lang.*; to use them without fully qualified names.
Consider the System.out.println() method we've been using since the first day of class.
System is really the java.lang.System class. This class has a public static field called out which is an instance of the java.io.PrintStream class. So when you write System.out.println(), you're really calling the println() method of the out field of the java.lang.System class.

Why are classes inside Scala package objects dispreferred?

Starting with 2.10, -Xlint complains about classes defined inside of package objects. But why? Defining a class inside a package object should be exactly equivalent to defining the classes inside of a separate package with the same name, except a lot more convenient.
In my opinion, one of the serious design flaws in Scala is the inability to put anything other than a class-like entity (e.g. variable declarations, function definitions) at top level of a file. Instead, you're forced to put them into a separate ''package object'' (often in package.scala), separate from the rest of the code that they belong with and violating a basic programming rule which is that conceptually related code should be physically related as well. I don't see any reason why Scala can't conceptually allow anything at top level that it allows at lower levels, and anything non-class-like automatically gets placed into the package object, so that users never have to worry about it.
For example, in my case I have a util package, and under it I have a number of subpackages (util.io, util.text, util.time, util.os, util.math, util.distances, etc.) that group heterogeneous collections of functions, classes and sometimes variables that are semantically related. I currently store all the various functions, classes, etc. in a package object sitting in a file called io.scala or text.scala or whatever, in the util directory. This works great and it's very convenient because of the way functions and classes can be mixed, e.g. I can do something like:
package object math {
// Coordinates on a sphere
case class SphereCoord(lat: Double, long: Double) { ... }
// great-circle distance between two points
def spheredist(a: SphereCoord, b: SphereCoord) = ...
// Area of rectangle running along latitude/longitude lines
def rectArea(topleft: SphereCoord, botright: SphereCoord) = ...
// ...
// ...
// Exact-decimal functions
class DecimalInexactError extends Exception
// Format floating point value in decimal, error if can't do exactly
formatDecimalExactly(val num: Double) = ...
// ...
// ...
}
Without this, I would have to split the code up inconveniently according to fun vs. class rather than by semantics. The alternative, I suppose, is to put them in a normal object -- kind of defeating the purpose of having package objects in the first place.
But why? Defining a class inside a package object should be exactly equivalent to defining the classes inside of a separate package with the same name,
Precisely. The semantics are (currently) the same, so if you favor defining a class inside a package object, there should be a good reason. But the reality is that there is at least one good reason no to (keep reading).
except a lot more convenient
How is that more convenient?
If you are doing this:
package object mypkg {
class MyClass
}
You can just as well do the following:
package mypkg {
class MyClass
}
You'll even save a few characters in the process :)
Now, a good and concrete reason not to go overboard with package objects is that while packages are open, package objects are not.
A common scenario would be to have your code dispatched among several projects, with each project defining classes in the same package. No problem here.
On the other hand, a package object is (like any object) closed (as the spec puts it "There can be only one package object per package"). In other words,
you will only be able to define a package object in one of your projects.
If you attempt to define a package object for the same package in two distinct projects, bad things will happen, as you will effectively end up with two
distinct versions of the same JVM class (n our case you would end up with two "mypkg.class" files).
Depending on the cases you might end up with the compiler complaining that it cannot find something that you defined in the first version of your package object,
or get a "bad symbolic reference" error, or potentially even a runtime error. This is a general limitation of package objects, so you have to be aware of it.
In the case of defining classes inside a package object, the solution is simple: don't do it (given that you won't gain anything substantial compared to just defining the class as a top level).
For type aliase, vals and vars, we don't have such a luxuary, so in this case it is a matter of weighing whether the syntactic convenience (compared to defining them in an object) is worth it, and then take care not to define duplicate package objects.
I have not found a good answer to why this semantically equivalent operation would generate a lint warning. Methinks this is a lint bug. The only thing that I have found that must not be placed inside a package object (vs inside a plain package) is an object that implements main (or extends App).
Note that -Xlint also complains about implicit classes declared inside package objects, even though they cannot be declared at package scope. (See http://docs.scala-lang.org/overviews/core/implicit-classes.html for the rules on implicit classes.)
I figured out a trick that allows for all the benefits of package objects without the complaints about deprecation. In place of
package object foo {
...
}
you can do
protected class FooPackage {
...
}
package object foo extends FooPackage { }
Works the same but no complaint. Clear sign that the complaint itself is bogus.