Using static let in enum instead of case - ios

I have noticed certain cases where inside an enum, instead of case people have used static let to declare variables. Is this practice justifiable?
public enum ExampleEnum {
static let case1 = "case1"
static let case2 = "case2"
static let case3 = "case3"
}

This is a quick way of creating a namespace for constants.
You can of course achieve similar effect using a struct, however running let foo = StructOnlyForStoringConstants() will not throw an error or even a warning (can be solved using private init or even logging a warning, but we quickly lose the quick in a quick way above) and hence might be confusing (some argue). Since enums without cases (or "no-case enums") cannot be instantiated, you don't have this problem.
Another reason is that putting constants in an enum might feel more natural (than say in structs), as enums are used for storing a group of related values.

Related

How to create a common property in swift4

I need a common property in my project so that I can use or share it thought out the application.
I have tried many solutions but didn't work.
I think it would make many things simple and reusable.
You can use Extension
as documented in
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/doc/uid/TP40014097-CH32-ID383
you can change previously defined classes properties
example
extension UIColor {
class var customGreen: UIColor {
let darkGreen = 0x008110
return UIColor.rgb(fromHex: darkGreen)
}
}
Make use of the iOS Design pattern "Singleton".
Its uses only one reference for a class and the same property will get reflected where ever you are using it throughout the app.
Reference : https://thatthinginswift.com/singletons/
You can create a lightweight "namespace" by declaring a public struct or enum. Then, simply add your static vars and you can safely share it.
As an added benefit, you get thread-safety for free. (Static stored property initializers are thread-safe.)
public enum SharedConstants {
public static var id = "MyID"
public static var hashCode = 12345678
}
By the way, extensions are great if you want to enhance an existing type. Type extensions let you add new functionality to a type without modifying its original code.
Yet, if all you need is a common shared property, extensions may not be the best choice.

How to avoid changing state in F#?

I have a C# WebAPI application that uses an F# library.
The F# library has a value:
let mutable CurrentCustomer:Customer option = None
I also have:
let Customers:Map<string,Customer> option = None
Both Customers and Customer are "global variables". On start-up the C# application loads a collection of customers into this global variable Customers. Then I have a customersController that has a Post, which calls an F# function setCurrentCustomer that sets the global variable CurrentCustomer from the collection stored in Customers:
// Post in customersController:
public HttpResponseMessage Post(string identifier)
{
var _customer = FSharpLibrary.setCurrentCustomer(identifier);
// code
}
// setCurrentCustomer function:
let mutable CurrentCustomer:Customer option = None
let setCurrentCustomer() =
CurrentCustomer <- customer |> Some
CurrentCustomer
Is there any way to avoid changing state by changing CurrentCustomer?
I know I could create a function that takes a CurrentCustomer object and returns a new CurrentCustomer object, but how will the customersController know what is the current customer set to?
Is there any way of avoiding having this global mutable variable Customer?
Is there any way to avoid changing state by changing CurrentCustomer?
Yes, there are many ways to do that, but most will involve changing the design of your FSharpLibrary so that it doesn't rely on mutable state.
As a completely general answer, you could apply the State Monad, but something less involved is often sufficient. Exactly what that would be, however, is impossible to answer without knowing what you are attempting to accomplish.
how will the customersController know what is the current customer set to?
It already knows, because it's setting the current customer to the identifier argument from the Post method. That value is in scope throughout the entire method.
The question is why your FSharpLibrary has mutable state? Can't you instead implement it with pure functions?

Struct or Enum to use for serialization keys?

Is there any reason why Apple prefers using structs over enums in the Lister demo for declaring keys for serialization? Is there might be some benefits?
For example:
private struct SerializationKeys {
static let text = "text"
static let uuid = "uuid"
static let completed = "completed"
...
//duplicated key!
static let descriptionText = "text"
}
Here we might have potential duplicates for keys. It's not a big question for small objects (don't forget copy/paste :)), but for large objects with tens fields it can be a real problem.
With enum we don't have such a problem:
private enum SerializationKeys : String {
case text = "text"
case uuid = "uuid"
case completed = "completed"
//...
case descriptionText = "text"
//here we have compiler's warning: Raw value for enum case is not unique
}
Will be happy to hear some thoughts on this.
I do the same thing, sometimes, and here's why.
With a struct, my values are directly available: so, if SerializationKeys is a struct, then SerializationKeys.text is a string.
But with an enum, the enum is the value. If SerializationKeys is an enum, then SerializationKeys.text is not a string; it's an enum. If I want the string, I have to fetch it explicitly, as the enum's rawValue. Sometimes, that's just too nutty. On the other hand, if it's acceptable, or if there's another reason why this makes a good enum, then fine, I'll use an enum.
To put it another way: if this is just a glorified namespace for some constants, a struct with static members seems simplest. An enum is for a switch, i.e. something that needs to exist in exactly one of several possible states.
Apple's reason for choosing a struct here seems to be purely semantic. SerializationKeys.descriptionText is a property. SerializationKey.DescriptionText is a type. And it is kind of semantically weird to use a type as a key.
True, in this particular instance the SerializationKey.DescriptionText type happens to have a "raw" value associated with it. But as I understand it, raw values are really only intended to be used as a sort of "bridging layer" layer between C enums. Using it for keys like this is kind of a hack.

Getting multiple references to the same method = multiple objects?

I'm new to Dart, so maybe I'm missing something here:
This works:
In my main(), I have this:
var a = _someFunction;
var b = _someFunction;
print("${a == b}"); // true. correct!
Where _someFunction is another top-level function.
This does NOT work: (at least not how I'm expecting it to)
Given this class...
class Dummy {
void start() {
var a = _onEvent;
var b = _onEvent;
print(a == b); // false. ???????
}
void _onEvent() {
}
}
Instantiating it from main() and calling its start() method results in false. Apparently a new instance of some function or closure object is created and returned whenever my code obtains a reference to _onEvent.
Is this intentional behaviour?
I would expect that obtaining multiple references to the same method of the same instance returns the same object each time. Perhaps this is intended for some reason. If so; what reason? Or is this a bug/oversight/limitation of VM perhaps?
Thanks for any insights!
Currently, the behaviour seems to be intentional, but the following defect is open since May 2012: https://code.google.com/p/dart/issues/detail?id=144
If I were to guess, I'd say that setting "var a = _onEvent;" creates a bound method, which is some sort of object that contains both the function as well as this. You are asking for bound methods to be canonicalized. However, that would require the team to create a map of them, which could lead to worries about memory leaks.
I think they made "var a = _someFunction;" work early on because they needed static functions to be constants so that they could be assigned to consts. This was so that they could write things like:
const logger = someStaticLoggingFunction;
This was in the days before statics were lazily evaluated.
In any case, I would say that comparing closures for equality is a edge case for most languages. Take all of the above with a grain of salt. It's just my best guess based on my knowledge of the system. As far as I can tell, the language spec doesn't say anything about this.
Actually, now that I've read (https://code.google.com/p/dart/issues/detail?id=144), the discussion is actually pretty good. What I wrote above roughly matches it.

Signature Files and Access Modifers in F#

I've recently been trying to learn the Object-Oriented aspects of F#, and have become curious about how to restrict access to types/modules in the language.
More specifically, I want to know the difference between writing this:
Example.fsi
module Stack =
val foo : string
Example.fs
module Stack =
let foo = "foo"
let bar = "bar"
and alternatively this:
module Stack =
let foo = "foo"
let private bar = "bar"
Do they not accomplish exactly the same thing in the end? Coming from a C# background, I'm much inclined just to use the access modifiers over signature (FSI) files. They seem to be more versatile (can apply to modules/types in namespaces, for example), whereas I don't any situation in which signature files offer something that access modifiers don't.
They accomplish almost the same thing. (Note that you can use an .fsi file for types in namespaces too, was unsure what your comment about that meant.)
A signature file has a couple advantages:
You can make entities public for the duration of the file, but then private to the subsequent files of the project.
You can have just your short summary in the signature file, so the public interface is easy to read without having to scan tons of code.
The first bullet is not to be trifled with - within-assembly encapsulation like this is actually a pretty huge feature for very large projects. Being able to define a few types which are public to one another within File1.fs, but then only have a subset of those types/methods be public to the rest (File2.fs, File3.fs, etc.) is quite useful (a little bit like 'friend' in C++).

Resources