text:
Why I'm not a React Native Developer
First published on September 21, 2016
- Introduction
- Pros
- Cons
- Conclusion
- Acknowledgements
- Changelog
- Comments
- References
Many people are currently assessing React Native as a platform to develop their next mobile app on. This is no trivial matter. Switching your software development platform involves a high setup cost and will profoundly impact your daily programming workflow. It is also one of the costliest decisions to reverse after anything substantial has been built.
Perhaps more importantly, your software development platforms also shape you as a software engineer. A software development platform encourages (or forces) the use of one language over another, prioritises certain architectures over others, requires using specific tools and workflows, and marries you to an entire ecosystem and its developer community.
Facebook wants you to switch:
And the React Native Team's sustained and painstaking efforts match the ambition. They've produced a software development platform so substantial that it can legitimately be considered a replacement for our traditional Xcode/Swift/ObjC stack.
Would it be a viable replacement? The blog posts I've read about React Native provide a rather cursory assessment of it. None has assessed its advantages and disadvantages with the depth you'd expect from someone trying to persuade you to change your software development platform.
Having spent several months using React Native, I have found that it is neither a platform I would develop in, nor a platform I would recommend the use of. This article proposes to provide a more thorough evaluation of the pros and cons of switching from Swift development to React Native, and will argue against the switch.
Declarative style
One thing I've found delightful about working with React Native was the declarative style in which the UI is programmed. In the React way of doing things, UI is a function of state and properties, whereas in Cocoa Touch, UI is imperatively written.
The following example will clarify what I mean. Suppose our UI needs to include a small square on the top left side of the screen, this small square should be red if, say, the user is connected and green if the user is not connected.
Here's how we typically do it on iOS:
class ViewController: UIViewController {
let indicatorView = ConnectivityIndicatorView()
override func viewDidLoad() {
let indicatorViewFrame = CGRect(origin: CGPoint.zero, size: CGSize(width: 20, height: 20))
indicatorView.frame = indicatorViewFrame
class ConnectivityIndicatorView: UIView {
var isConnected: Bool = false {
didSet {
if isConnected {
backgroundColor = .green
} else {
backgroundColor = .red
override func didMoveToSuperview() {
let weAreConnected: Bool = arc4random()%10 > 4
self.isConnected = weAreConnected
In the imperative style, you specify all the steps required to update the UI. We need to listen for changes in
isConnected and update the view accordingly. We tell iOS how to compute state.
Compare this with React's declarative way:
Simply express how your app should look at any given point in time, and React will automatically manage all UI updates when your underlying data changes.
class Root extends Component {
render() {
return (
<ConnectivityIndicatorView />
class ConnectivityIndicatorView extends Component {
constructor() {
this.state = {
isConnected: false
componentDidMount() {
var weAreConnected = Math.floor(Math.random() * 10) > 5;
this.setState({ isConnected: weAreConnected });
render() {
var color = this.state.isConnected ? 'green' : 'red';
return (
<View style={{'backgroundColor': color, 'width': 20, 'height': 20}}>
React's declarative style makes you describe your UI with React within the view's
render() method. The React framework ensures that any changes in state trigger re-rendering. Changes in your data (i.e. when
backgroundColor changes) automatically trigger a change in the UI.
This effectively does away with you manually updating views in response to changes in the model. Whether or not you like being relieved of that responsibility, React does a very good job at ensuring that the updates are carried out according to your descriptions, and you no longer have to worry about rolling out and maintaining a property setter for that
isConnected variable. All you update is the state.
You'll also notice that you end up reasoning of UI elements as if they were functions rather than instances of classes. They take in state and render a UIKit object. The purpose of a
Component is to return itself in the state it's supposed to be, when requested.
I found it to be a useful way to think about UI. And it's a good evolution from MVC, with the View being just responsible for displaying itself and not for managing data, a welcome departure from
UIViewController and its turning a blind eye to incestuous relationships between V and C.
Faster iterations
React Native's appeal isn't just intellectual, the framework will appeal to the pragmatically minded too.
When you program in React Native, the framework will create a local server that serves the JavaScript files you're working on. You build the app once, run it on the iOS Simulator or a device, and React Native ensures that any changes you make in the JavaScript are reflected in the app.
You're given two options:
- Live Reloading will reload the app every time you edit and save one of its files. Basically saves you from switching to the Simulator and pressing
- Hot Reloading doesn't reload the entire app, it only reloads the file you just edited. If, say, you're working on the UI of a table view cell deep inside a navigation stack, the change will be immediately reflected in the cell you see in the Simulator, you won't have to navigate from the startup screen to the cell to see the changes. And the component will stay in the state it's already in. It's a WYSIWYG programming experience, a luxury that Xcode has never afforded you for your apps.
I remember having to add a debug method in AppDelegate for every ViewController I'd want the app to show on startup, so that I wouldn't have to manually navigate down to it every time I'd run the app to see the changes I had just coded in. Hot Reload now makes me feel like a caveman.
React Native's feedback loop is bewitchingly low. It takes less than one or two seconds between you saving a file and seeing the change in your app. That's easily ten times less than the typical Build and Run cycle we're used to in Xcode.
This allows over-the-air code updates. Any changes in your JavaScript code can be instantly pushed to your users while the app is in production.
Remember that graceless and awkward conversation?
"Great app! Does it run on Android? […] Oh. And when do you plan to release an Android version? […] Oh."
Your codebase can now create an app that can run on millions of additional devices, and you've increased your outreach by several orders of magnitude.
And I can attest that the same codebase will reliably produce the same-looking and same-acting app on both platforms.
Being able to produce an Android incarnation of your app from the same codebase, graphically and functionally equivalent to its iOS counterpart, is empowering.
The obvious advantages of any cross-platform frameworks are always compelling: market development, unified codebase, and a unified skill set required to maintain the app's codebase.
Uncertain roadmap
A major concern with using React Native is the lack of long-term commitment for the project.
If this project were a mere plug-and-play component of my app, like a networking library or an SVG to
CGPath renderer, its long-term survival and maintenance is a secondary concern of mine; for if its developers abandon it, or if its pace of development is unsatisfactory – sad as that may be – I can replace it with a roughly equivalent library or take up maintenance myself. It might be a big deal, but in any case it won't be a huge deal; I make sure to have loose enough couplings with all my third-party libraries/CocoaPods to ensure that the whole project doesn't collapse if one library stagnates or goes missing.
But React Native is not a plug-and-play CocoaPod, it's not a mere SDK, it's not a mere library, it's an entire software development platform. Saying my app has a "tight coupling" to it would be an understatement, my app is entirely dependent on it. If Facebook stops maintaining React Native, my app will stagnate, and there won't be a "React Native replacement" at my disposal. If I want to carry on development of it myself, I'll have to get familiar with the the React Native source, as well as the React.js codebase, the React Native CLI tools, and
JavaScriptCore. Will the community ensure the project survives? Maybe – and if it does it probably will not be at the pace that we're used to.
On the GitHub repository you'll see a new React Native release at a healthy pace of roughly once every two weeks. Not bad for a software development platform that targets two separate and complex software development platforms. Promising as that may be today, Facebook hasn't made any long-term commitments to maintaining React Native for a sustained period of time. The company hasn't provided any guarantees that it won't pull the plug on the project – not just for the foreseeable future, but for the lifetime of your app. In other words, you currently don't have any guarantees it'll ever be compatible with iOS 11, or 12.
Here's to the next year!
Ends an official React Native blog post from April 2016. What about the ones after? Facebook is worryingly silent about that.
We will publish plans quite soon - Konstantin
Said the React Native team, back in December 2015. Those plans haven't yet been published. The results of Facebook's long-term cost-benefit analysis of React Native, if there ever was one, sound less awesome than you thought.
Again, we're not talking about an individual Cocoapod, we're talking about the only platform your code can run on. It's the kind of thing you do need very-long-term visibility on, and you don't have any.
Patently daunting
Alongside its permissive BSD-style license, React Native ships with Facebook's Additional Grant of Patent Rights, Version 2. Facebook's motives for including this file aren't clear, nor is the file itself.
It's a bipolar document. Right after the document grants you a "perpetual, worldwide, royalty-free, non-exclusive, irrevocable" license to use React Native, we are served with the following clause:
The license granted hereunder will terminate, automatically and without notice, if you (or any of your subsidiaries, corporate affiliates or agents) initiate directly or indirectly, or take a direct financial interest in, any Patent Assertion: (i) against Facebook or any of its subsidiaries or corporate affiliates, (ii) against any party if such Patent Assertion arises in whole or in part from any software, technology, product or service of Facebook or any of its subsidiaries or corporate affiliates, or (iii) against any party relating to the Software.
I'm not a lawyer, so I've asked a lawyer to help me clarify this (and if you're not a lawyer you should too). According to him, that clause boils down to this: if I initiate any lawsuit alleging patent infringement against Facebook, my license to use React Native would be immediately terminated. (I've quoted his more detailed breakdown in the Appendix below.)
In practice, this seems like a deterrent to me suing Facebook over patents. By implication, it also seems to give Facebook a good deal of breathing room to infringe my patents ("nice quantum physics technology you have here, would be a shame if something bad were to happen to your app").
You may find the above interpretation pessimistic. But you should be pessimistic when evaluating software licenses and patents. We assess the efficiency of our algorithms in terms of how well they perform in the worst possible scenario. I think that's how we ought to evaluate software licenses and patents too – for exactly the same reasons.
A linear search algorithm will perform optimally in scenarios where the target value happens to be the first in the list, but that fact alone isn't sufficient to persuade me of using linear search algorithms in any given scenario. If it is possible for the target value to be the last in the list, my linear search algorithm's average performance will be very poor.
Likewise, the fact that Facebook happens not to be a serial IP infringer today reassures me little if it is possible for Facebook to become a serial IP infringer tomorrow and punish any retaliation from my side by revoking my license to use React Native. If Facebook were to infringe my IP tomorrow (however unrelated to my software it is) and I sue them for it, I have given them the right to pull the plug on my app.
What I'm jeopardising here is both the platform my app depends on as well as my intellectual property.
iOS apps enter the App Store entirely at Apple's discretion. I don't want to multiply that uneasy feeling by two.
Patently silent
Is the interpretation above correct? Is that worst-case scenario a possibility? Do I have a good reason to be worried? Do I have a good reason not to be worried?
In various GitHub issues and forums posts, developers have claimed that their legal departments have advised them not to use React or React Native precisely because of this clause. Matters remain deplorably ambiguous for developers who don't have a legal department at hand.
More worryingly, Facebook hasn't made any substantial efforts to clarify matters. A 2015 post on the Facebook Open Source blog acknowledges this "confusion" and cheerfully announced clarifications to its Additional Grant of Patent Rights. More than five related GitHub issues later, the fog hasn't cleared.
Various Facebook developers have responded to the issues, attempting to reassure developers while making it clear that whatever they wrote was not an assurance of anything. One of them even offered links to discussions of the issue on Reddit and Hacker News – unhelpfully, and rather misleadingly.
This has turned into an exercise in hermeneutics and speculation over a question of genuine importance: Can Facebook revoke its React Native license? If so, under what conditions?
October 2017 update: Facebook Relicensing
"[A]fter several weeks of disappointment and uncertainty for our community", Facebook relicensed React, Jest, Flow, and Immutable.js under the MIT license. Sadly, React Native's license and patent haven't changed since this article was first published.
I commend the claim that the Facebook people "don't want to hold back forward progress for nontechnical reasons", but I struggle to see which technical reason they have for maintaining the above situation for React Native.
February 2018 update: Facebook Relicensing again
As of 17 February, 2018, Facebook relicensed React Native as MIT 👍
A crucial downside to switching to React Native from Swift is the technical regress: you have to adopt and use JavaScript, a language that's
- technically defective
- unsafe
- slowly evolving
Allow me to argue why.
All the examples of JavaScript code hereafter will be of valid JavaScript (ES2016) code
Javascript's inadequacy
One of my favourite bumper stickers proclaims:
Safety is no accident
At first sight, the wit in this quip lies in its double meaning. We are offered a definition of safety as the absence of accidents and the suggestion that it is the product of a set of safeguards.
Is safety the product of the safeguards baked into your car, such as seat belts and airbags, or of your safe driving?
The answer, of course, is both in equal measure.
Drivers should prefer cars that have the widest amount of safeguards built into them. Not because they make driving easier, but because they decrease your chances of having a preventable accident.
Likewise, a programming language should offer safeguards against programmer error.
The fact that millions of drivers productively drive cars without wearing a seatbelt isn't a good argument for cars with no seat belt. Similarly, the fact that millions of JavaScript developers productively use an inherently unsafe language isn't a good argument for the use of unsafe languages.
The importance of safety in a programming language is one that I appreciated as the tools for iOS development evolved.
When Automatic Reference Counting came to Objective-C, you had the option to switch it off for your iOS project. Why was it a bad idea to switch off ARC? Because the compiler could now perform an evaluation of the lifetime of your objects that was more accurate than yours. "The compiler is smarter than you" was the mantra, and that was certainly the case at least as far as reference counting was concerned. I remember how satisfied I was to realise that my
EXC_BAD_ACCESS runtime crashes were decimated as a result.
Objective-C gives you the option of setting the type of a variable to
id, which stood for "any type whatsoever". But it is bad practice to use it for a variable whose type you know because it opens the door to runtime crashes – that the compiler could prevent. If it's a problem that the compiler can solve, you let the compiler solve it – and tackle interesting problems instead.
You'll remember
unrecognized selector sent to instance crashes. You were calling a method on an object that didn't respond to it. Type error. Third of all my bugs.
Unsurprisingly, one of my first reactions after using Swift was "this was made by someone who got tired of preventable runtime crashes in Objective-C".
Swift is safe. The compiler won't let you pass in an
Int to a function that expects a
String. In fact, if the compiler isn't able to infer a type, you have to explicitly set it.
But JavaScript lacks these safeguards against programmer error, making preventable runtime crashes and preventable programmer errors part of your routine.
Type errors
The language does not enforce type of variables and parameters to functions:
Any variable can be anything at any time:
var j = null
var j = function foo() {
return j
var j = 23
var j = 'hello'
console.log(j) //hello
JavaScript makes you believe that it has some notion of types and class, with keywords like
typeof, and
class Person {
//nobody is immortal:
isImmortal() {
return false
var p = new Person()
console.log(typeof p) //object
console.log(p instanceof Person) //true
console.log(p.isImmortal()) //false
p.isImmortal = function() {return true}
console.log(p.isImmortal()) // true
console.log(p instanceof Person) //true
Here we see the following:
- JavaScript's notion of "class", "type", and "instance" is completely different from the majority of the programming world.
- types serve no useful purpose in JavaScript, as it's too easy to unreliably define a type.
Remember those
unrecognized selector sent to instance crashes? Thought they were no longer part of your life? Here's their incarnation in React Native:
Lack of optionals
A very large amount of bugs in Objective-C code (and in many other older programming languages) are due to programmers inadvertently calling methods on objects that are
In the world of React Native and JavaScript, this error is common:
And preventable, both in theory and in practice.
Swift did away with this problem by implementing optionals, which force you to take required
nil checks if you know that an object can be
Lack of function signature
In JavaScript, functions don't have a return type, you don't know what can be returned by the function, or if it returns anything at all.
var foo = 'im a number'
function divideByFour(number) {
return number / 4
console.log(divideByFour(foo)) //NaN
Let's make this even more fun. In JavaScript, any expression can be evaluated at any time by any function. Consider this example using two functions from the JavaScript standard library;
map, which is supposedly the equivalent of Swift's
map, and
parseInt, which parses a string into an integer.
var foo = ["1", "2", "3"].map(parseInt)
console.log(foo) //[1, NaN, NaN]
This messed up result is due to the fact that
parseInt takes two parameters
(val, radix) but
map passes it 3 parameters
(currentValue, index, array). Still totally legal JavaScript (a language that some people consider viable for functional programming).
JavaScript's support for immutability is very poor.
There is a
const operator, which helps ensure primitives don't get mutated. But anything that's not a primitive is as malleable as jell-o:
const array = [3, 6]
array[32] = 9
console.log(array) // [3, 6, 32: 9]
const foo = function() {
this.number = 42
const bar = foo
bar.number = 999
console.log(foo.number) // 999
Unique copies? Nope. Any unique object could be modified by any part of your app at any time. Good luck multithreading. Indeed,
Much of what makes application development difficult is tracking mutation and maintaining state.
Says… Facebook, in the documentation of Immutable.js. (A framework designed to bring immutable data structures to JavaScript.)
But here's how you enforce immutability in React.
You politely ask the developers to not mutate state. Yes, that's a screenshot from the React documentation.
You can't trust arrays
You thought arrays were a "systematic arrangement of similar objects, usually in rows and columns"? Think again.
var array = [0,1,2]
array["hello"] = "watsup"
array[6] = 999
for (var index in array) {
console.log(array[index]) //0,1,2,999,watsup
for (var index of array) {
console.log(index) //0,1,2,undefined,999
array.forEach(function(value, key, array) {
console.log(value) //0,1,2,999
console.log(array[5]) //undefined
JavaScript arrays have more in common with ordinary JavaScript objects than with what we'd call an array. Their lack of precise sequentiality and mutability doesn't make them well-behaved.
Poor error handling
In JavaScript, you can have any function throw a runtime error or exception, without warning.
function tenDividedBy(number) {
if (number == 0) {
throw "can't divide by zero"
return 10 / number
You can throw anything you want as an exception; a string, a
Date, a function, etc. There is no mechanism for you to mark a function as potentially crashing your teammate's code or for specifying how to process an exception. Use
if statements instead, say the docs:
It's best to leave exceptions as a last line of defense, for handling the exceptional errors you can't anticipate, and to manage anticipated errors with control flow statements.
No support for decimals
Given that most decimal fractions cannot be accurately represented as binary fractions in hardware, many programming languages (including JavaScript and Swift) will often produce mathematically incorrect decimal arithmetic:
console.log(0.1 + 0.2) //0.30000000000000004
console.log(0.1 + 0.2 === 0.3) //false
Which is why other languages' standard libraries often have support for decimal fractions (in Swift, for instance, we can use
Decimal). In JavaScript, you have to resort to using a third-party library – or write your own.
Dodgy maths
Remember to be careful with primary school arithmetic too. JavaScript has a complicated relationship with
0 and things that are not numbers.
var a = 0
var b = -0
console.log(a === b) // true
console.log(1/a === 1/b) // false
var x = Math.sqrt(-2)
console.log(x === NaN) //false
console.log(isNaN(x)) //true
console.log(isNaN('i like pumpkins')) //true
Unsafe initialisation
JavaScript allows for objects to be left in an inconsistent state right after being created, as their properties don't need to be initialised.
class Rectangle {
constructor (width, height) {
this.width = width
this.height = height
area () {
return width * height
class Square extends Rectangle {
var myRect = new Square()
console.log(myRect.area()) // ReferenceError: width is not defined
Optional curly braces after an
Curly braces after an
if statement are optional:
if (1 > 2)
console.log("ha"); console.log("he")
To add that taste of adventure to your control flow statements.
Ambiguous curly braces
Unless programmer intent can be very accurately inferred, a language shouldn't let curly braces be optional.
function foo() {
{a: 4}
console.log(foo()) //undefined
Switch fallthrough
If you forget to include a
break statement in a clause of a
switch statement, you fall through. Also, a
switch statement doesn't carry out checks for case exhaustivity.
var j = 32
switch (j) {
case 32:
console.log('spot on')
case 0:
/* prints:
spot on
What's nothing?
var foo;
foo === null; //false
foo === undefined; //true
Yes, something that's not
null could be nothing for all intents and purposes. Not a helpful distinction.
And what if you want to know whether a variable contains any data? Well, for your checks to be exhaustive, you need to check for both
null and
if (foo !== null && foo !== undefined) {
Poor expressivity
- No enums. Let alone enums with associated types. Good luck reliably representing state.
- No
- No generics.
- No
wherestatement to increase expressivity of control flow statements.
Exceedingly slow evolution
Behold, ES2016 brought these new features to JavaScript:
- The
includesmethod for arrays.
It checks if an array contains a specified value. Here's how you use it:
var array = [1, 2, {"hello": 32}]
console.log(array.includes({"hello": 32})) // false
var foo = 32
var bar = foo
var otherArray = [bar, 23]
console.log(otherArray.includes(foo)) // true
Try not to.
- The ** operator
To be used for exponentiation.
a ** b is shorthand for
Math.pow(x, y).
Consider this: Python's
** operator was in Python 1. Ruby's
** operator has been in Ruby for more than 20 years.
So it took JavaScript 20 years to add a basic arithmetic operator and a quite limited membership-checking method for arrays, as a year's worth of improvements.
Flow to the rescue!
Flow is Facebook's answer to many of the above grievances. It's a static type-checker for JavaScript, capable of inferring and tracking the types of the variables in your code, and alert you of impending doom.
Recall my example above about the problems that arise from lack of function signature in JavaScript (the
divideByFour function which expects a number but is fed a string). Here's how Flow would deal with it:
// @flow
var foo = 'im a number'
function divideByFour(number) {
return number / 4
/* console output:
8: console.log(divideByFour(foo))
^^^^^^^^^^^^^^^^^ function call
5: return number / 4
^^^^^^ string. This type is incompatible with
5: return number / 4
^^^^^^^^^^ number
Found 1 error
This fixes many of the problems that occur from JavaScript's lack of enforceable function signature.
It can also produce the equivalent of generic arrays:
// @flow
class J {
var b = function() {
return 2
var array = [1, new J(), b]
function giveMeAnArrayOfNumbers(numbers: Array<number>) {}
/* console output:
13: giveMeAnArrayOfNumbers(array)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function call
9: var array = [1, new J(), b]
^ J. This type is incompatible with
11: function giveMeAnArrayOfNumbers(numbers: Array<number>) {}
^^^^^^ number
13: giveMeAnArrayOfNumbers(array)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function call
9: var array = [1, new J(), b]
^ function. This type is incompatible with
11: function giveMeAnArrayOfNumbers(numbers: Array<number>) {}
^^^^^^ number
Found 2 errors
Flow deals very well with nullability, and will warn you if a value you'd expect not to be
null might be
// @flow
var j = null
function greet(name) {
console.log("hello " + name)
/* console output:
6: console.log("hello " + name)
^^^^ null. This type cannot be added to
6: console.log("hello " + name)
^^^^^^^^^^^^^^^ string
Found 1 error
j is supposed to be a
string, but could be
null at any point in time, Flow encourages us to annotate it accordingly. It is thus able to complain if we don't carry out null-checks before feeding it to anything that needs it to be a non-null
// @flow
var j: ?string = null
function greet(name: string) {
console.log("hello " + name)
if (j != null) {
/* console output:
No errors!
Flow's features go positively beyond type-checking and annotation, and add support for new constructs. One of them is literal types, which we can use to build, for example, enums.
// @flow
type CompassPoint =
| "North"
| "South";
class Compass {
direction: CompassPoint;
degrees: number
constructor(degrees: number) {
this.degrees = degrees
direction(): CompassPoint {
if (this.degrees > 270 || this.degrees < 90) {
return "North"
else {
return "South"
And Flow will complain if
direction returns anything that's not
"North" or
Another construct I find useful is Union types, which constrain a value to be one and only one of a predefined set of types. Here's an example from the Flow docs:
// @flow
type U = number | string;
var x: U = 1;
x = "two";
Flow is great friends with React Native, as long as you help it help you. The Flow docs offer a good example of how what happens when you correctly annotate the
proptypes of your component:
const Greeter = React.createClass({
propTypes: {
name: React.PropTypes.string.isRequired,
render() {
return <p>Hello, {this.props.name}!</p>;
<Greeter />; // Missing `name`
<Greeter name={null} />; // `name` should be a string
<Greeter name="World" />; // "Hello, World!"
The comments indicate where the Flow warnings appear, adequately reprimanding you for not fulfilling your own contract.
Flow's an altogether powerful tool. Here are some examples of the useful things its command-line interface lets you do:
suggest Shows type annotation suggestions for given files
type-at-pos Shows the type at a given file and position
get-def Gets the definition location of a variable or property
Flow's like flossing
Is JavaScript fixed now? No.
Impressive as an engineering effort Flow may be, it remains a superset of JavaScript and thus forces you to build on inherently weak foundations. Hailing Flow (or TypeScript, for that matter) as any kind of remedy for JavaScript's faults reminds me of Swamp Castle and its King (from Monty Python and the Holy Grail):
When I first came here, this was all swamp. Everyone said I was daft to build a castle on a swamp, but I built it all the same, just to show them. It sank into the swamp. So I built a second one. That sank into the swamp. So I built a third. That burned down, fell over, then sank into the swamp. But the fourth one stayed up. And that's what you're going to get, lad, the strongest castle in all of England.
The fact that things can be built on unsafe foundations does not make the foundations any safer, nor does it make the process any more efficient. And our insisting in perpetrating this exercise makes us lose sight of its preposterousness.
Perhaps more revealingly, JavaScript supersets, linters, or static analyzers are really palliative measures to mitigate the fact that you're dealing with a platform that doesn't give you a choice of a safer language – if it did, you wouldn't have to resort to using them.
There is another fundamental problem with these palliative measures. Safeguards, like laws, are worth very little if they're not actually enforced by the authorities and respected by the community.
Flow doesn't stop you from building and running React Native apps with code bound to generate runtime crashes. And that is a basic safety requirement for a programming language: if it's a preventable error, the language should actively prevent it, it should stop me from writing and running unsafe code by default, not as an afterthought.
It just should not be possible for my teammate to write functions that are ambiguous as to their return value, it should not be possible for me to call an method on an object that doesn't respond to it, it should not be possible for someone to not define
proptypes on a component and me having to manually point out during code review that
proptypes should have been defined.
Flow, like unit testing and flossing, has the curse of being beneficial and optional and wearisome. It's in your next year's resolutions.
And that's the reality: how many public
.js files on GitHub use flow (i.e. contain
@flow to signal they're Flow-checkable) ? Roughly 1,400,000 out of roughly 80,000,000 public
.js files. That's… less than 2% public usage of a tool to write safer JavaScript.
On a more relevant note, out of the hundred React Native repositories over at
awesome-react-native, I wasn't able to find one that made any significant use of Flow and its type annotations. Nor was I able to find a single React Native tutorial mentioning (let alone advising you) the use of Flow.
The Javascript Ecosystem: balls and chains
JavaScript's deficiencies seem to impress everyone except JavaScript developers, for whom the aspects of JavaScript that I outlined above are not awful warts, they're "quirks" or "gotchas" that you, not your language, have to be on the lookout for.
This is because JavaScript developers also don't believe that JavaScript is inadequate.
The language has no support for immutability? Let's make a library. The language has no support for typing? Let's make a library. The language has no support for decimals? Let's make a library. The language doesn't allow safe functional programming? Let's make a library. Language has no support for nullability? Let's make a library.
Or… given that you acknowledge that those features are fundamentally important, you could just… switch to a language that supports them out of the box? (I don't know, I'm just throwing ideas out there.)
To my mind, there is a generalised obstinate refusal to see JavaScript as inherently deficient and therefore needing replacement rather than polishing. The resulting proliferation of grafts and crutches is seen as signs of a vibrant ecosystem, whereas what it really shows is that the language is lacking in fundamentally important functionality.
The situation is illustrated very well by this cartoon:
"Freedom from digging" is simply choosing a language that has built-in support for the things you need. This digging is not a good use of energy. JavaScript is not naturally conducive to good software engineering also for this reason: it forces you to develop and depend on things that other languages offer by default.
typeof(null) === 'object' ? Well, there was a proposal to change the type of
null to
null. But
it turned out that it broke a lot of existing sites. In the spirit of One JavaScript this is not feasible.
And the proposal was rejected. As of ES06,
null is still
JavaScript's evolution, which caters to the needs of:
- millions of different outdated browser users
- a set of disparate browser vendors
- billions of websites and their respective developers
is admirably democratic. But on the other hand, it will be much slower than that of other languages, and it probably won't prioritise developer ergonomics as much as portability.
Wider angles
From a historical perspective, the pattern we're seeing here, of a seemingly deficient language gaining popularity and being repudiated by the incumbents of the platforms it wants to take over, is poignant and familiar.
Come sit by the fire (of the past flame wars) and I'll tell you a story.
Back in 1994, Richard Stallman wrote to the newsgroup
comp.lang.tcl an article unambiguously titled "Why you should not use Tcl". Stallman was sourly unforgiving of Tcl's shortcomings as a programming language, and denounced what he saw as Tcl's unfitness for purpose. The parallels with my own grievances against JavaScript are spectacular:
The principal lesson of Emacs is that a language for extensions should not be a mere "extension language". It should be a real programming language, designed for writing and maintaining substantial programs. Because people will want to do that! […] Tcl was not designed to be a serious programming language. It was designed to be a "scripting language", on the assumption that a "scripting language" need not try to be a real programming language. So Tcl doesn't have the capabilities of one. It lacks arrays; it lacks structures from which you can make linked lists. It fakes having numbers, which works, but has to be slow. Tcl is ok for writing small programs, but when you push it beyond that, it becomes insufficient.
His article effectively triggered the Tcl War of 1994. Of all the responses he received, I found John Ousterhout's (who created Tcl) the most imposing:
Language designers love to argue about why this language or that language must be better or worse a priori, but none of these arguments really matter a lot. Ultimately all language issues get settled when users vote with their feet. If Tcl makes people more productive then they will use it; when some other language comes along that is better (or if it is here already), then people will switch to that language. This is The Law, and it is good.
Ousterhout's counter-attack strikes on many of the fronts I've been active in, so his artillery is worth taking a closer look at.
(Some readers will notice Ousterhout argues circularly: "Why do people switch to a language? Because it is better. Why is it better? Because many people switched to it." His argument deserves a more generous interpretation nevertheless, not least because we often see this line of reasoning in many other arguments for any specific tech stacks, such as, you guessed it, React Native.)
According to Ousterhout, programming languages have features that can make them better a priori (i.e. purely intrinsic characteristics such as programming paradigm, syntax, standard library, or portability) and features that can make them better a posteriori (i.e. widespread adoption by many developers). It doesn't matter that Language A is a priori better than Language B, if Language A isn't a posteriori better than Language B.
In other words, adoption trumps technical superiority (regardless of how language designers define superiority).
Ousterhout's argument fits on a record cover:
The more fans a singer has, the better he is. The point is that popularity, whether it's quantified by fans or hit records, is a good criterion for evaluating singers.
But the fact that a language enjoys widespread adoption and can boast a sparkling app showcase should not influence your judgement as to its merits.
A gallery of complex or nice-looking apps built using Technology X only means that Technology X may be used to build complex or nice-looking apps; but not that it's an optimal tool for the job.
Dozens of sandcastle competitions across the world show you the beautiful structures you can build using just sand and water. That may warrant the assertion that sand is a great toy, but sandcastle competitions alone shouldn't be enough to convince you that you should build your own house out of sand. Yet many are convinced.
The King of Swamp Castle is the king of many Hackers.
Similarly, popularity is an unreliable criterion for evaluating programming languages. For a pretty basic reason: popularity may very well be the result of vendor lock-in (like being the only programming language that can be run in a browser), bandwagon effects, or legacy codebases.
The intrinsic characteristics of a programming language (such as its safeguards against programmer error, standard library, portability, etc.) are what you should base your criteria on. They are the basis for productivity gains.
In fact, many things lead to negative productivity gains. For example:
- lack of safeguards to prevent you making avoidable errors
- a tiny standard library, unfit for most purposes
- syntax and semantics that don't let you express your intent clearly
- a slow pace of development
- All the above (JavaScript)
React Native has a total of 648 dependencies.
Not particularly surprising, as dependency chains can be long in the world of
npm, React Native's package manager.
This showcases the comradeship of open source: your app is built on more than 600 people's sustained efforts.
This is also a pitfall: you depend on 648 volunteers to keep maintaining their library for the lifetime of your app, without any formal commitment.
Will their licenses stay compatible with your software? Hopefully.
And will they all implement best practices in security? Or can you tolerate 648 separate potential security risks?
Better alternatives
If cross-platform development is what drew you to React Native, consider your options.
React Native faces strong competition from two established cross-platform development platforms: Xamarin and Appcelerator.
Both Xamarin and Appcelerator offer support for iOS, Android, and Windows Phone. They both have:
- more comprehensive APIs
- more mature IDEs
- better documentation
- clearer and friendlier licensing
- equal (if not better) performance
Xamarin development is in C#, which is usually less bug-prone and more expressive than JavaScript. If you believe in JavaScript, Appcelerator development is in JavaScript.
Compared to React Native, both Xamarin and Appcelerator have better prospects at longevity. Appcelerator (the maker of Titanium) (runs on apps installed on 350 million devices) was acquired in January 2016, and Xamarin (used by more than one hundred Fortune 500 companies) was acquired in February 2016 (by Microsoft). Both had previously raised more than $80M in equity funding.
Projects are more likely to survive and thrive in this red ocean of cross-platform frameworks (I recently counted more than ten in active development), if they're backed by companies whose business is to supply me with a reliable software development platform.
(An honorable mention goes to Flutter, a cross-platform development platform (iOS and Android) being written by Google. It uses a language that's safer and more expressive than JavaScript (Dart), it helps you follow principles of Material design, and produces natively compiled code. Unlike Xamarin and Appcelerator, it's open-source. It's currently not production-ready, but it's promising nonetheless.)
Good software development platforms have four essential features.
- Portability – can target more than one platform.
- Productivity – the maturity of its IDE and other development tools, documentation, and expressivity of its development language.
- Safety – the extent to which the platform prevents you making mistakes.
- Longevity – how likely the platform will be around for the lifetime of your app.
Even though our industry (still) has no established open standard to measure these, I'd like to offer my evaluation based on my experience and research.
React Native's strengths in terms of portability and productivity are outweighed by its shortfalls in safety, the uncertainty about its long-term roadmap, and a daunting patent license:
Mature platforms such as Xamarin and Appcelerator offer the best portability (with support for Windows phone), their mature development tools and choice of programming language will also offer gains in productivity and safety, and the fact that they are the core product of well-funded companies offer good assurances of longevity:
Swift development is a winner in terms of safety, longevity, and productivity. Its portability is relatively low but not negligible: it does not allow you to build an Android version of your app, but it allows you to build a macOS version, and lets you write the app's server backend:
And that is why I am not a React Native developer.
My thanks to Rami Chowdhury and Alkis Papadakis for their helpful feedback on early version of this article. Thanks also to Greg McMullen for helping me decipher esoteric IP texts.
You can track this article's edits here.
Follow and participate to the discussion of this article on Hacker News, Hacker News (again) and /r/programming.
You can read a Korean translation of this article here (courtesy of canapio).
- We are the Team working on React Native AMA
- How to pitch React Native to Developers
- Classic Programmer paintings: "Functional programmer listens to JavaScript claims"
- React Native at Artsy
- React Native: A Year in Review
- Hacker News Discussion: Node.js is one of the worst things to happen to the software industry
- npm Meltdown Security Concerns
- https://blog.addjam.com/react-native-its-not-all-sugar-and-spice-cb5d6b25eae9#.gy4fxnpxz
- The King of Swamp Castle, from Monty Python and the Holy Grail
- The Three Big Lies About JavaScript
- Review: Xamarin in 2015 - Data Corruption and Swift are Not Helping
- Product or Process?
- StackOverflow question: Difference between strongly and weakly typed languages?
- Let's Make A Webpage In 2016
- Why JavaScript is the Future of Programming
- Using React Native: One Year Later
- Redmonk Language Rankings 2016
- Seth Godin: This is Broken
- Argumentum ad populum
- Hacker News Discussion: Why C++ sucks (2016 edition)
- React Native it's not all sugar and spice
- ECMAScript Wiki: harmony:typeof_null
- Cube Drone: Relentless Persistence
- Wat
- YourLanguageSucks
- Defective C++
- JavaScript ES6 Features
- awesome-react-native GitHub repository
- Types, by Gary Berhnhardt
- All you wanted to know about types but were afraid to ask, by Joseph Abrahamson
- Stallman vs. Ousterhout
- Ousterhout vs. Stallman
- Visualisation of React Native's npm dependencies
- Updating Our Open Source Patent Grant. Blog post from Facebook's Open Source Blog.
- "Legal Department did not allow use of React". Forum post from the React Discussion Forum.
- License clarification #7293. Issue opened on the React repository.
- Reconsider restrictions in patents file #402. Issue opened on the React Native repository.
- Please reconsider restrictions in PATENTS (Additional Grant of Patent Rights Version 2) #8952
- Update PATENTS #3554. Ambitious pull request on the React repository.
- clarification on PATENTS grants and termination clauses #3617. Issue opened on the React repository.
- Facebook relicenses React, Jest, Flow, and Immutable.js under the MIT license
Appendix: A more detailed breakdown of React Native's Patent issues
From Greg McMullen.
# None of this is legal advice! Just my reading of the license. If you want advice specific to you, see your own lawyer.
# If you sue Facebook for patent infringement and any of these three conditions are met, the license is terminated.
You (or any of your subsidiaries, corporate affiliates or agents) initiate directly or indirectly, or take a direct financial interest in, any Patent Assertion
(i) against Facebook or any of its subsidiaries or corporate affiliates,
(ii) against any party if such Patent Assertion arises in whole or in part from any software, technology, product or
service of Facebook or any of its subsidiaries or corporate affiliates,
(iii) against any party relating to the Software:
The license granted hereunder will terminate, automatically and without notice.
# If Facebook sues you for patent infringement, you can make a patent infringement counter-claim against them without the license being terminated.
1) Facebook or any of its subsidiaries or corporate affiliates files a lawsuit alleging patent infringement against you in the first instance,
2) you respond by filing a patent infringement counterclaim in that lawsuit against that party that is unrelated to the Software,
The license will not terminate due to such counterclaim.
# Just to be clear, the license also won't terminate if Facebook sues you and you don't make a counterclaim


text:
The Singapore Watch Club
The Singapore Watch Club was founded less than a year ago, when me and a few like-minded watch enthusiasts got together on a Saturday afternoon to talk about watches over coffee. The gang got larger and larger and became the tight-knit community we have today. My first horology moment occurred when I peered into the display caseback of a mechanical watch. Those tiny little springs and gears, they work together with such precision to keep track of what is basically our existence on earth. Our fascination with the elusive and abstract concept of time creates an intimate relationship between man and watches. I began my horological journey and the more I explored, the more I got sucked further into it. Some of the master watchmakers' undying strive for perfection inspired me even outside of horology. It is without question that watchmaking is an art form. At the same time, it's also a product of research,development and innovation. A balancing act of artisanal tradition and scientific engineering. The Singapore Watch Club strives to bring together people with the same admiration and curiosity for the art of watchmaking. This passion, need be the only common denominator. As with most forms of art, one man's meat can be another man's poison. We cherish all educated opinions, and learn through our confabulations. Ultimately we're looking to heighten our level of appreciation for watches, sophistication as buyers, and mature together as a community. Watch collecting can be a solo hobby, but it is so much more fun and engaging with like-minded members. We aspire to be a friendly and united community, fuelled not only by passion but also friendship and growth.
The Clubhouse
The Singapore Watch Club's web portal strives to satisfy the community's thirst for information. We'll bring you the latest news, reviews and on-goings in the horological universe. The Club's activities will also be documented here. This is in line with our vision to disseminate news, ideas and opinions to a wider audience, at a deeper level.
The Forum
When acquiring a new timepiece, we all have our own sets of boxes that we want checked. One attribute that most collectors look out for is resale value. The relationship between resale value and retail performance is direct and evident, the same can be said about the resale market (secondary) and retail market (primary). These 2 markets complement each other at equilibrium. A strong secondary market contributes to a flourishing primary market, instilling confidence in buyers that their timepiece holds undeniable intrinsic value and demand. We strive to bring new efficiency to the market with our forum, a platform for collectors to buy and sell their timepieces. Providing transparency and visibility on secondary market performance, and in turn translating to confidence and strength in the primary market.
I welcome you to explore what The Clubhouse has to offer and I hope you enjoy your stay.
Singapore Watch Club will continue to strive to bring about even more added value content to
all watch enthusiasts.
Best Regards,
Tom Chng

subset: commoncrawl


text:
As a result of "at least 350 sites in Iraq being contaminated during bombing" with depleted uranium (DU) weapons, Nermin Othman said, the nation is facing about 140,000 cases of cancer, with 7,000 to 8,000 new ones registered each year.
Speaking at a ministerial meeting of the Arab League, she also complained that many chemical plants and oil facilities had been destroyed during the two military campaigns since the 1990s, but the ecological consequences remain unclear.
"Our ministry is fledgling, and we need international support; notably, we need laboratories to better monitor air and water contamination," she said.
The first major UN research on the consequences of the use of DU on the battlefield was conducted in 2003 in the wake of NATO operations in Kosovo, Bosnia, and Montenegro. The UN Environment Program (UNEP) said in its report after the research that DU poses little threat if spent munitions are cleared from the ground.
"Health risks primarily depend on the awareness of people coming into contact with DU," UNEP writes in its 2004 brochure "Depleted Uranium Awareness."
No major clean-up or public awareness campaigns have been reported in Iraq.


text:
What if? It's easy as a sports fan to put on the retroscope and look at any game and ask 'what if?' Unfortunately for the Seminoles, this will be a game that not only receives a lot of 'what ifs' tonight and tomorrow but also from here until the end of their season. This was a missed opportunity for the Seminoles to take sole possession of third place in the conference and put themselves in a good position to be guaranteed a bye in the ACC tournament. Now, they have work to do.
Clemson did not score for the first seven minutes of the game. That should have been game, set, match with Florida State cruising to victory. If that wasn't enough, the Tigers had another four minute scoring drought in the first half. Game over, right? The Seminoles only had a 19-6 lead with just over four minutes to go in the first half. One would think that would have been the time to put the game out of reach. Instead, Clemson went on a 13-2 run to finish the first half only down by two points.
Clemson started the second half with an 8-0 run. They out scored the Seminoles 21-2 over a seven minute thirty eight second stretch that bridged halftime. Florida State worked its way back into the game only to see Clemson move ahead again. This occurred twice before Florida State appeared to take control of the game with about ten minutes to go. In a game that really felt that the first one to 50 would win, the Seminoles opened up a six point lead. One would think that in a game that neither team could score, that would be enough to get the job done.
It wasn't. With 2:35 to go, Tanner Smith hit a three point shot from the corner. Smith was shooting 28.4% from deep on the season. From that point forward, Seminoles fans had a sinking feeling in their stomach and a sense of deja vu: missed free throws and turnovers. Chris Singleton missed two free throws with 1:24 to go. Solomon Alabi went 1-2 from the line with fourteen seconds to go. Michael Snaer had a turnover on an inbound pass that led to an Andre Young three pointer on the next possession. It was one thing after another.
All of that led to the Seminoles having the ball with seven seconds to go and down by three points. Dulkys ended up with the ball in the corner in front of the Seminoles bench. Trevor Booker recognized the play and left the post to defend Dulkys. It resulted in a block. There was not shot fake. Dulkys went right up with the shot only to see Booker come down with it. Six seconds were left on the clock. Booker gets fouled, makes two free throws. Game over.
It was a terrible game for both teams. Florida State had an eFG% of 38%. Clemson had an eFG% of 33%. Clemson had an offensive efficiency of 80. Florida State had an offensive efficiency of 79.9. The big difference in the game was the free throw shooting and turnovers. Florida State shot 58% from the strip compared to 78.9% for the Tigers. And to cap it all off, Florida State turned the ball over on 31.9% of their possessions.
It's time to move on. Wake Forest rolls into the Tucker Center on Wednesday night. In order for Florida State to go 10-6 in conference play, they must win that game. Florida State can still finish in third place in the conference, but they will need some help. At this point, aiming for a first round bye is reasonable, but they need to win both of the remaining games.


text:
Code, the basic building block for creating computer software, apps and websites, is practically ubiquitous in today's tech-driven world.
Yet the majority of people has little understanding of how it works, much less are able to use it.
With the aim of introducing more Queen's students to coding the Engineering Society is hosting its first coding competition. The two-week event offers up some prizes as well as bragging rights for the top coder but the real goal is to get more students involved in coding, says Robert Saunders (Sc'19), Director of Information Technology for the society.
"The competition's not really about the prizes. It's about getting people involved," says the computer engineering major. "You never know, one student who doesn't know anything about coding can sign up and fall in love with it. For me, the competition is a way to leverage my position to get people involved in coding."
The competition is open to all Queen's students no matter their skill level and utilizes HackerRank, a website where users can practice on coding problems or set up competitions. Those who sign up to compete will face a series of coding questions that they will have to solve to earn points. The competitor with the most points wins. If there is a tie, the winner will be decided on time.
"Technology is so huge now, it's really important to get involved. Even if you have the most basic skills for coding at least you have some sense of how things work," says Mr. Saunders, adding that the site can be used as a learning tool. "When you are doing a problem (HackerRank) asks you to write your code but what's different about it is you're not just submitting the code to the platform for us to review, it also runs test cases through your code. It shows the user the process of a computer kind of feeding input to your program and getting the desired output, which is nice."
Competitors do not have to be on Queen's campus and can use their own computers. Sign up is free but does require a Queen's email address.
Visit the Engineering Society Coding Competition site for more information or to participate.
Following the competition Mr. Saunders has also organized the Engineering Society Startup Workshop on Feb. 28 from 6-9 pm. The workshop will focus on project management, team communication, user interface and experience design, version control and issue tracking systems.


text:
Murder. Romance. And the bizarre.
The Murder Collection
Pt. 1
Emporium Press
January 18, 2017
Cover art: Dianne Thies, Lyrical Lines
Copyright: Emporium Press / C.S. Poe
Genre: Amateur sleuth mystery, romance, choose your own adventure
I wasn't going to create any worthwhile art by staying in bed for three weeks. Not that I expected to suddenly be struck with a lightning bolt of inspiration today. After all, the only reason I'd showered, shaved, and put on clean underwear was because I'd run out of TV shows to binge-watch on Netflix.
Maybe I shouldn't have tried so hard my thesis year in art school. Then I wouldn't have come out swinging, wouldn't have sold my first collection for an obscene amount of money, and now wouldn't be where I am today. You know, paying for both a work studio and separate apartment in New York City, eating ramen noodles for dinner every night in an attempt to stretch my savings and cover just one more month of rent, while dealing with the impossible task of painting something better than my already best. Such is the life of an artist, amirite?
Anyway, my publicist was done tapping his foot and giving me the stink eye. He'd moved right on to threatening to sever ties with me altogether if I didn't show him my next big project.
"Dean, you're hot right now. You've got to produce while people still remember your name. While people still give a shit!"
I unlocked my studio door and stepped inside.
Jeff Delaware came at painting from a business standpoint.
I came from— well, the art standpoint. And great art can't be rushed. Otherwise I'd just paint shit.
"Maybe if I painted shit with shit…." I muttered thoughtfully, shutting the door behind me. Not that I'd actually… you know. I mean, I prefer oils, thank you.
But speaking of shit. What the hell was that smell? The studio was pretty big, and seemed completely untouched from the way I'd left it at the beginning of the month. The ceilings were high, and the ventilation definitely worked because I didn't need to be killing myself with turpentine fumes.
And yet, something smelled awful. Like… turpentine. But there was more. Garbage? Hot garbage? A dead animal? A bag of crap set on fire? Jesus!
I covered my nose with the sleeve of my jacket and walked around the studio, eventually stopping outside of the water heater closet.
"Oh God." It was coming from inside.
Dean opens the closet.
Dean leaves it be.


text:
Accessibility mode is enabled
Development review bodies are established to make decisions on land use actions and to recommend land use policy to the City Council.
Click on the arrow to learn more about the various legislative meetings managed by the Community Development Department.
Policies | Accessibility | Social Media | Website Feedback © 2013 - 2022 City of Sacramento


text:
Flavourful Chicken cooked in a mild gravy made with spices, tomatoes and yogurt.
|Whole chicken
|1 , cut into pieces
|Lemon juice
|1 Tablespoon
|Ginger garlic paste
|2 Teaspoon
|1 Teaspoon
|Chili powder
|1 Teaspoon
|Garam masala
|1 Teaspoon
|Salt & pepper
|To Taste
|2 Teaspoon
|1 Tablespoon
|Red kashmiri chilies
|Red onion
|1 , sliced
|Black mustard seeds
|1 Teaspoon
|Ginger and garlic paste
|2 Teaspoon
|1/2 Teaspoon
|Garam masala
|1/2 Teaspoon
|1 Large , finely chopped
1. Marinade chicken in lemon juice, ginger garlic paste, turmeric, chili powder, garam masala salt, pepper and yogurt for minimum an hour.
2. Heat oil in a pan, saute kashmiri chilies, red onions and black mustard seeds. Cook until onions are nice and brown. Remove from the pan and set it aside.
3. Saute chicken in oil for 3 to 4 minutes or until chicken is nice and brown.
4. Add ginger and garlic paste and mix that in. Drop in some turmeric and garam masala, give it a good mix.
5. Throw in some chopped tomatoes and then add the fried onions. Cover and cook for about 30 minutes or until chicken is nice and tender. Stir at regular intervals and keep adding water as desired.
6. When the chicken is tender, add yogurt 2 tablespoon at a time and fold that with the chicken.
7. Serve creamy chicken with rice or roti. Enjoy.
Serving size
Calories 718Calories from Fat 445
% Daily Value*
Total Fat 49 g75.4%
Saturated Fat 13 g65%
Trans Fat 0 g
Sodium 485 mg20.21%
Total Carbohydrates 8 g2.7%
Dietary Fiber 2 g8%
Sugars 4 g
Protein 57 g114%
Vitamin A % Vitamin C %
Calcium % Iron %
Calories 3590Calories from Fat 2225
% Daily Value*
Total Fat 245 g377%
Saturated Fat 65 g325%
Trans Fat 0 g
Cholesterol 0
Sodium 2425 mg101.05%
Total Carbohydrates 40 g13.5%
Dietary Fiber 10 g40%
Sugars 20 g
Protein 285 g570%
Vitamin A 0% Vitamin C 0%
Calcium 0% Iron 0%
*Based on a 2000 Calorie diet


text:
Whether you are adopting technologies individually or planning a digital transformation overhaul,
PoCs are a key step in achieving your innovation goals.
Proof-of-Concepts are central to corporate innovation.
They used to be a frustrating bottleneck, a necessary price to pay.
But we think you deserve better.
With an intuitive solution and state-of-the-art technology,
prooV turns the PoC process into an innovation catalyst.
With prooV, all of your open innovation and proof-of-concept activity is centralized on one PoC Platform. You can configure your environments, discover the right vendors to participate in your PoC and evaluate their compatibility with your company's infrastructure all in the same place.
The Team Management feature means that all of your PoC stakeholders stay aligned with each other's work as the PoC process progresses, and everyone stays on the same page with access to necessary documents, instructions and more.
With all of your PoC management tools and information easily accessible on one cloud-based platform, your PoC process is faster, smarter and more advanced.
Security and privacy regulations like the GDPR shouldn't keep you from running productive, innovation-fueling PoCs.
From your PoC data to your PoC environments, prooV gives you all the tools you need to ensure a completely secure PoC process for your company and your participants.
For example, with our state-of-the-art Deep Mirroring technology you can test and evaluate software solutions using data that behaves exactly like your production data, without exposing it.
prooV Firewall lets you add an extra layer of security to your PoC environment and additional measures to your PoC management by defining extra security rules. You can grant specific IP addresses access to designated environments, or grant external parties access to only the PoCs they are helping you with without giving them access to the entire platform.
Our Deep Mirroring technology powers our Data Mirroring tool that allows you to automatically generate data that mimics the patterns and behaviors of your real production data. By using a small subset of data, you can easily generate millions of records to populate your PoC testing environments.
You can also add anomalies to your mirrored data, allowing you to make your PoC results even more reflective of real life scenarios.
Data Mirroring gives you all the benefits of running a PoC with real data, but with none of the risk.
For each PoC, fill your analytics dashboard with the Key Performance Indicators (KPIs) that matter most to your business.
The performance of every vendor that participates in that PoC will then be measured according to those KPIs throughout the testing period so you can compare solutions, follow their progress and evaluate them all according to the same metrics at the end of the PoC.
There are more than 170 predefined technical KPIs for you to choose from, or you can use the KPI editor to create your own business KPIs.
prooV provides the first ever tech-powered PoC process.
Our proprietary, patented solution is based on the most advanced algorithms and technologies so that your innovation journey can be as ambitious as your innovation goals.
The patented Deep Mirroring technology learns sophisticated data structures and high-level relationships between data using classification algorithms such as Natural Language Processing (NLP) and Gaussian Mixture Model (GMM), along with deep learning and data science technologies.
Configure customized environments for each individual PoC with the PoC Wizard. It makes articulating your PoC goals, needs, evaluation criteria and instructions, as well as defining the requirements for corresponding environments, an intuitive step-by-step process.
Further replicate your production environment with Smart APIs to ensure smooth communication between legacy systems and the vendor solutions you are testing.
With Behavior Mirroring, fueled by our Deep Mirroring technology, you can further enhance your environment customization by recreating your production network behavior within your PoC environments.


text: His career has fizzled ever since the Rihanna scandal, but Chris Brown is still trying to work on repairing his shattered image. Brown's latest stunt involved shedding a bucket of tears while performing a tribute to his idol, Michael Jackson, at last night's BET Awards. The supposed compassion failed to impress this cynic. What did you think of the hoopla?


text:
[[As D.C. Smythe looks on in annoyance, Valerie Smith steps away from her partner to address the "away team" directly.]]
Smith: [Smiling apologetically] No, no, it's no trouble. It's just my PARTNER failed to mention he was bringing anyone else into this investigation. Just concerned about too many cooks in the pot, and all that...
Smith: [Turning serious] We've bee trailing an international anarchist hacking group calling themselves "theNullBoyz". They're completely anonymous and notoriously difficult to track.
[[We peer over Smith's shoulder as Fooker, Sharon, Lt. Johnson, and Trudy listen intently.]]
Smith: They've recently executed a serious of high-profile, coordinated cyber attacks against the world's largest financial institutions, including several large banks and stock exchanges.
[[D.C. Smythe steps up beside Valerie as she continues.]]
Smith: Their biggest claim to fame is a cryptic proclamation that "economic Armageddon is at hand."
Smythe: However, we suspect there's more to this threat than what's on the surface...


text:
The Chill (Title From Ross Macdonald)
"Uh-oh," said Bernie, gazing down into the freezer. "I wasn't expecting this. Truth is, I was kind of expecting Ray."
I rose up, got my paws on the edge of the freezer, looked in. The smell was getting out now, so I knew what was in there, just not who. All it took was one glance: Albie Rose, in his little bathing suit; and also with a hole in his forehead, not very big.
Tags: Albie Rose, Ray
This entry was posted on Tuesday, June 15th, 2010 at 8:45 am and is filed under Chet The Dog. You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.


text:
Today's business jet owners as well as their crewmembers and passengers are demanding inflight connectivity rivaling that which they enjoy every day on the ground. Connectivity in the air is no longer considered a perk but, rather, a necessity. However, with increased connectivity comes the same security issues everyone everywhere is facing: Our data, communications, and networks are vulnerable to an increasing variety of threats and privacy issues.
Business aviation and internet security
At a recent Aero Club of Washington, D.C., meeting, Alan Pellegrini, president and CEO of Thales USA, manufacturer of electronic systems for aviation, told attendees that, the more connected aircraft become and the more devices that are added to this intricate web of connectivity, the more vulnerable our aircraft become to safety, security, and privacy threats. According to the Avionincs article, "There have already been hacks of aircraft and aviation-related systems, including in-flight entertainment systems, data communications between pilots and ground-based controllers, and airline operations systems that in one case in Europe caused flight cancellations."
Disruptions in private aviation systems can and do have tremendous economic and social impacts. That's why aviation has long been a target of terrorists. In fact, Russian hackers attempted to break into U.S. civilian aviation systems in 2017 as part of a larger attack on the electrical grid. While the attack did not escalate past early stages, it illustrates industry vulnerability.
One big trend in cybercriminals targeting business travelers is malicious actors gaining access to sensitive business information and using this inside information for illicit stock trading. In one incident, hackers compromised a hotel's computer network and stole access codes as well as network credentials that allowed them to search for valuable business information.
In addition, cyberattacks on airborne private aircraft are already occurring, usually from attackers on the ground. And offering unsecured Wi-Fi to flight crewmembers and passengers can actually make this type of hacking easier due to hackers' ability to connect as well.
Another complicating factor involves the implementation of Automatic Dependent Surveillance-Broadcast (ADS-B) equipment. While ADS-B is said to be the next generation of air traffic control technology, it compromises privacy by broadcasting unique International Civil Aviation Organization (ICAO) addresses and Flight IDs, making them available to those with the proper receivers. This is a reason some owners are resisting compliance with the ADS-B regulations, which will be mandatory as of January 2020.
Protective measures
Companies and individuals involved in business aviation need to take steps now to ensure they are not victims or even unwitting enablers of security attacks. Be aware of who, why, and how hackers might want to break into your systems. Conduct a security audit of your facility and processes to assess how tight your security is. Understand how you control physical and virtual access, what types of monitoring are in place for your users and systems, and where vulnerabilities may exist in your processes and systems. Train your flight crewmembers on security best practices such as avoiding open Wi-Fi networks and protecting access credentials.
Many flight department managers are hiring IT security experts to harden their systems against security breaches and keep up with the continually evolving threat landscape. It's important to have a detailed action plan so you and your crewmembers are prepared in the case you discover a vulnerability or breach. Yours should address how to limit its impact and recover quickly as well as outline backup equipment and processes in case of critical failures.
Security is a wide-ranging and ever-changing but vitally important aspect of private and business aviation. Keeping your aircraft, flight crew, passengers, computer systems, and data safe and secure requires continuing education, secure systems and practices, and constant vigilance. That's the price for a strong, economically viable business aviation operation that can withstand today's ever-present cybersecurity threats.
You can reach our sales specialists today at email@example.com, call us any time at +1 (305) 754-3313, or visit us online.


text:
India's Vivanta hotel heads to Heathrow
India's largest hospitality company, Indian Hotels Company Limited (IHCL), will open a Vivanta hotel at Heathrow Airport in London in partnership with Hayre Group Limited.
Recover your password.
A password will be e-mailed to you.
Recover your password.
SIGN UP FOR FREE(New User)
Be part of our community of seasoned travel and hospitality industry professionals from all over the world.


text:
Let me go back a century and tell you a story. My grandfather was a medical practitioner in the Bihar of 1920s. He had a brood of children who were orphaned due to his untimely death. Two of my uncles had just about finished high school when he moved on. Their older brothers could not afford to send them to college. The two had to be gainfully employed, somehow, as soon as possible. They were taken to Tata Steel, an hour away from where they lived. Tata Steel and the government of Bihar were the only two employers you could think of in a five-hundred mile radius of my uncles' hometown. The possible work one could get at Tata Steel was that of a technologist-engineer or of a manual worker. So, what could be done with the two boys with their high school qualifications? They were neither fish nor fowl. "Take them to the lab," someone said. A German technician who ran the place was looking for a few hands. The burly German took a hard look at the two. Then he showed them a broom standing at one corner of the lab and asked them to sweep the floor. By the end of day, one of the two just ran away. To him, it was too much to handle. The one who stayed back retired as a chief supervisor of Tata Steel. The difference between the two? The one that stayed on was not trying to seek 'job satisfaction'. Instead, he focused on satisfying the job.
The more prosperous the industry, the higher the number of people looking for this elusive thing called 'job satisfaction'. Similarly, the more qualified some people are, the higher is their need for 'job satisfaction'. Sometimes, it is as elusive as seeking 'true love'. There are times when we get lucky deservedly or otherwise. But we also get used to it and conclude that it is the responsibility of the organization to maintain a continuous supply of job satisfaction.
Whenever I think of job satisfaction, I remember all those who have to work at night-policemen, airline pilots, nurses and doctors, ambulance drivers and hotel staff, and of course the sentinel of the snow and the desert and the mountains. Do their jobs 'satisfy' these people or do these people satisfy the jobs with which they have been entrusted? Are jobs living things that can ever 'satisfy' us?
In the corporate world, like any other place, when we open the bonnet and look under it, we find a whole bunch of tough, dirty but strategic tasks that must get done for the bacon to come home. Sometimes, they are so tough and so dirty that they overshadow the strategic nature of the job. So, all such jobs have to be 'sold' to prospective incumbents. More they are sold, less buyers they attract. Often, the man who takes up the job is either a loser who has no other choice, or someone who just views it as a transit camp. For many potentially high-performance individuals, a false sense of survival, desire for glamour or just the need for creature comforts make these jobs undesirable. "I would rather be in Kolkata than be posted to Mungher." "I rather have the corporate planning job than be collecting bad debts." Or, consider this one here: "Give me a cerebral job, I do not enjoy handling transactions…"
Few of us ever ask the boss to be rewarded with a tough and dirty job. We only look for the 'plum' ones. Yet, there are people, who given a tough and dirty job, make it strategic: they transform the job in unbelievable ways. In a typical career span, there must be at least four such solid stints in one's life to make the person a solid professional. All the great people I know have been in the trenches for much of their lives, and their inventory of bruises outnumber the commendations they have received. The occasional commendations stay on the wall. It is the bruises that these people carry with pride.


text:
As far as I know, President Barack Obama never said that if you like your life insurance options, you can keep them. He may therefore get off the hook as a deceiver if the Dodd-Frank regulatory law does what is now plotted, though he will still share responsibility for the insurance provision that along with others could bloody lots of noses.
A conglomeration of marketplace interventions lovingly promoted by the president, Dodd-Frank is slowly but surely headed our way. It's true that different agencies had been too busy bumping into each other and wrestling with complicated passages to get all the rules written, but Obama called the regulators in to tell them, by golly, to start regulating. And so, befuddled or not, the regulators are coming.
The idea behind the law – officially known as the Wall Street Reform and Consumer Protection Act – is to make sure we never have another financial crisis of the kind we had in 2008. It was supposed to address the issue of too big to fail, does so only questionably and is ultra-filled with a jumble of bureaucratically empowering irrelevancies and potentially damaging guesstimates. This collaboration of the intellectually presumptuous and the ideologically driven is finally too big to succeed.
One of its inexcusable forays has been to include some life insurance companies among institutions regarded as posing threats to the financial system if something goes terribly awry. A not infinitesimal issue is that they do no such thing.
If companies failed in insurance pursuits, many people would suffer, but the financial system would not be affected in a major way. It is additionally observed that states have done a reputable job overseeing them and that the companies themselves have done a remarkable job of sound, alert management. Intervene foolishly, and, as Iain Murray of the Competitive Enterprise Institute has written with reference to a study, purchasers could someday have fewer choices in policies that could also cost more and return less.
Members of both parties in Congress are wise to this stupidity and just maybe, conceivably, will do some little something about it, though that would be a meager start to what is really needed. We need bold, enlightened souls to further reshape Dodd-Frank and, beyond that, to reduce the rest of our egregious regulatory excess. Right now the mishmash exceeds an astounding 134,000 pages of federal rules that are more than a little punishing, as an underpublicized study underlines.
Two economists (John Dawson and John Seater) estimated that federal regulations promulgated over the past 60 years may have made Americans about one-fourth as well-off as we would be without them. If, then, you want some rough notion of what a more liberated economy might possibly have done for you, multiply your current income by four.
But wait. Weren't many of those regulations really, truly needed? Yes, of course. But many weren't and are constitutional affronts. As a Wall Street Journal series showed, a vast number have even led to criminal charges against people who could not possibly have known they were violating any stricture, a practice aspiring to despotism.
Look, too, at how nothing is too tiny to generate colossal governmental consternation. Right now, the Federal Trade Commission is going after a 137-year-old, nonprofit music association for suggesting to its members – mostly piano teachers – that they shouldn't try to recruit students from each other. A Journal columnist, Kim Strassel, notes that the group has had to a turn over thousands of documents, sign a silliness-ridden consent decree and submit to a burdensome, costly 20-year antitrust compliance program.And for what? Proffering an admonishment.
It's craziness that won't affect most of us the way new life insurance rules might and Obamacare is increasingly doing, but helps describe the current reign of in-your-face bullies.
Jay Ambrose, formerly Washington director of editorial policy for Scripps Howard newspapers and the editor of dailies in El Paso, Texas, and Denver, is a columnist living in Colorado and a senior fellow at the Independence Institute. Email firstname.lastname@example.com.
Our unofficial motto at Complete Colorado is "Always free, never fake, " but annoyingly enough, our reporters, columnists and staff all want to be paid in actual US dollars rather than our preferred currency of pats on the back and a muttered kind word. Fact is that there's an entire staff working every day to bring you the most timely and relevant political news (updated twice daily) from around the state on Complete's main page aggregator, as well as top-notch original reporting and commentary on Page Two.
CLICK HERE TO LADLE A LITTLE GRAVY ON THE CREW AT COMPLETE COLORADO. You'll be giving to the Independence Institute, the not-for-profit publisher of Complete Colorado, which makes your donation tax deductible. But rest assured that your giving will go specifically to the Complete Colorado news operation. Thanks for being a Complete Colorado reader, keep coming back.


text:
Are you thinking of getting a cat? Or perhaps you already own one and are wondering how long you can expect it to live. The good news is that a domestic cat that is well taken care of can enjoy a fairly long life, and can expect to live much longer than other pets such as dogs.The average lifespan of a cat out in the wild is four to five years. Outdoor cats that spend most of their time outside also tend not to live beyond the age of five. Domestic cats who live indoors, on the other hand, enjoy a considerable boost to their lifespan, clocking in at thirteen to seventeen years on average. Some indoor cats can even live up to twenty years or longer. Dogs, on the other hand, usually live only ten to thirteen years depending on their size and breed.
How Breed Affects The Average Lifespan of a Cat
How long a domestic, indoor cat is likely to live depends partly on its breed. The following cat breeds are among the longest-lived, enjoying an average lifespan of fifteen to twenty years: American Short Hair, Australian Mist, Balinese, Bombay, Burmese, European Short Hair, Himalayan, Japanese Bobtail, Korat, Nebelung, Persian, Russian Blue, Siamese, Turkish Angora, and Turkish Van. Mixed breeds tend to live longer than purebred cats.
Other cat breeds have lifespans that range from approximately ten to fifteen years. These include the Abyssinian, American Bobtail, Bengal, Birman, Blue Chartreux, British Short Hair, Burmilla, California Spangled, Ceylon, Chantilly-Tiffany, Colorpoint Short Hair, Devon Rex, Egyptian Mau, Exotic Short Hair, German Rex, Havana Brown, Javanese, La Perm, Main Coon, Munchkin, Norwegian Forest, Ocicat, Oriental, Selkirk Rex, Siberian, Singapura, Somali, Sphynx, and Tonkinese. The American Wire Hair, Cymric, and Manx are among the shortest-lived breeds, with average lifespans in the seven-to-twelve-year range.
A Few Steps You Can Take To Increase Your Cat's Life Expectancy
Although cats are unlikely to live longer than eighteen or twenty years, there are a few things you can do to make sure your cat doesn't die prematurely:
1. Make sure your cat feels safe and happy.
Stress and anxiety can contribute to premature death in our pets. You should provide your feline companion with a comfortable bed and safe space. You should also aim to interact with your cat regularly, provide him or her with cat toys for entertainment, and if at all possible, get a second cat so they can keep each other company. Even though indoor living is associated with a longer lifespan, some domestic cats truly enjoy going outdoors so you may want to consider letting your pet roam in your yard (under your supervision) every once in a while.
2. Monitor your cat's health and take him to regular checkups at the vet.
Regular visits to the veterinarian will make sure your cat has access to preventative health care such as vaccines and tick preventatives. It will also ensure that you catch any diseases early, making it more likely that your cat will survive the illness. Even paying close attention to your cat can be helpful, as you'll be able to tell if your cat is acting strangely and should visit the vet for a checkup.
3. Feed your cat a healthy and nutritious diet.
Make sure you follow your veterinarian's feeding guidelines and buy the best quality food you can afford. Good nutrition can go a long way in ensuring that your cat lives a long and healthy life. Fresh foods free of harmful chemicals are better than overly processed meals made up of animal byproducts and preservatives. Just as it is in humans, being overweight can lead to health problems and early death in cats. Lower body weights are associated with longer lifespans, so make sure your cat doesn't get too heavy!
What is the Absolute Longest My Cat Can Live?
Sadly, even if your cat is a long-lived breed and you take all the steps above, your cat won't live forever. A female cat named Creme Puff from Austin, Texas is the longest-living cat ever recorded. She was born on August 3, 1967, and died on August 6, 1995, living a record-breaking thirty-eight years and three days. Creme Puff made the 2010 edition of the Guinness Book of World Records. Creme Puff aside, twenty years is likely the upper limit of most cats' lifespans. Make sure you make the best of them with your companion!


text:
Last week, we were happy to welcome a number of businesses in the South West to our breakfast event, Forcewest at Bristol's famous cycle cafe, Mud Dock. The subject was migrating from Salesforce Classic to Lightning, and the Desynit team covered off a couple of different angles in their presentations. If you were not able to make the event, here is a round up of some of the key insights.
There are a lot of businesses out there who are yet to transition to Salesforce Lightning
Salesforce Lightning came out in 2015. You may remember it. It was launched to with a huge song and dance at Dreamforce and hailed as The Future of Enterprise Technology. The problem was, it wasn't really ready. There were considerable product gaps and still had some way to go before you could migrate.
Fast forward to Feb 2019, and now it's fair to say that Salesforce Lightning is fully formed and completely ready to go. Salesforce are not selling Classic anymore – if you buy a Salesforce licence now you go straight to Lightning. In fact Salesforce are not updating Classic either, the features released with each new platform update are all in Lightning now.
In which case, you would imagine that most businesses had by now made the move to the new platform.
Surprisingly, you would be wrong – the picture is more mixed than that. Our audience at the Forcewest were all on Salesforce Classic, to some degree. About 50% of Desynit's own customerbase are yet to migrate fully. And another Salesforce consultancy attending our event told us that about 80% of their customers were still working on Classic.
Everett Rogers nailed it in his Diffusion of Innovation theory, back in the 60s. Basically, the idea is that adoption of new, innovative ideas takes place in a predictable curve, as the idea percolates through groups and takes hold. You've probably seen the graph. So while the Salesforce Lightning product itself might well have reached maturity, perhaps we are still waiting for the late majority and the laggards to read the news. But, if Everett knew his stuff, then everyone will eventually get there.
So what is the truth? In terms of an actual percentage of Salesforce customers, only Salesforce know the answer to that question, definitively. But what we do know is this: Salesforce Classic is not coming back.
You have to tackle those complicated Visualforce pages
One of the main issues that we have seen customers encounter with their Salesforce migration relates to handling the transition of complex customisation to the new UX. Unfortunately in scenarios which deploy some complexity – possibly even some bespoke Visualforce code – it's not as simple as switching over to Lightning and getting on with things.
Our Advanced Salesforce Developer, Simon Lawrence, presented on just this topic at Forcewest and blogged about this issue here, as this is really worth exploring in some more detail. The issue is that often these bespoke little corners of your Salesforce org are doing a lot of heavy lifting in terms of business operation, and now you are faced with a complete rethink. Technology has moved on, not just the User Interface, it goes deeper than that. Lightning Components have replaced coded solutions, so it might be time to completely re-engineer what you've got in place. The good news is that the result will be far more robust and future-proofed, in terms of scalability and maintainability.
So in summary, tackle these issues now, they are not going to go away. It might be cost effective to talk to Desynit about bringing in some additional technical expertise for these discrete issues.
How do I build an effective Lightning Migration plan?
Over to Jenny, our Salesforce Advanced Admin, to provide the answers to this one.
Her key advice was to start with the tools that Salesforce provide. First port of call us is the Lightning Readiness Report, which allows you to see exactly where you are at the click of a button.
This same report also gives you a helpful estimate on the amount of time this project is going to take – that is, how many hours will you need to sink into this.
Two points..
Firstly, do take the projected number of hours with a pinch of salt. Yes, in theory, you could switch over in a flash. However, as we've said before, this is your opportunity to fix those areas of your org that need more attention. That's going to take some time: not just time actually working away at your user interface, but time spent talking to your Salesforce stakeholders and finding out how they would ideally like to work. Don't underestimate the importance of this – it's worth committing some time to this activity.
Secondly, you don't have to just run this report once. You can run this report before, during and after your migration if you want. It will serve as a handy progress checker.
Migration to LEX is a people challenge, not just a tech challenge
Finally, this particular insight was one which came up within our wider discussion with our guests once the presentations were over. Bringing in new technology that replaces old is a change project, and needs to be treated as such. Don't underestimate the importance of communicating to your users – they need to know why you are migrating, what's expected of them and what's the benefit to them. Communication is the key word here. We've blogged about building an effective comms programme to drive adoption previously here. When you consider that migrating to Salesforce Lightning is in effect a Salesforce (re)implementation, then you can see that all the same rules apply.
Do you have any questions on Lightning Migration? We would really like to hear from you. Post a comment on this blog or get in touch with the Desynit team and we will see what we can do to help. We do offer packages businesses either looking for some support with their transition, or indeed can take on your migration project in it's entirety. Leave us your details in the form below and we can email you the information.
[pardot-form id="17105″ title="Lightning Transition Services"]


text:
Helping streamline productivity and minimize cost.
The ongoing challenge for all businesses is to find solutions that enable better efficiency.
Premium Resources offers extensive experience and solutions to help businesses run better.
Premium Resources develops strategies for small and medium-size businesses focusing on efficiency improvement and profitability. We provide relief from many administrative/HR functions that don't add value, enabling your business to focus on its core competencies.
Our goal with every client: reduce costs, improve benefits, and lower risk. We accomplish this through a strategic mix of services customized to your unique needs.
If you think you might be able to do things better, you're probably right. And Premium Resources can provide objectivity and solutions to get you on your way to improving your business.


text:
This felt is a blend of wool and rayon, and is beautifully smooth and strong (approximately 2mm thickness). I love the subtle mottled colours which give a lovely natural effect.
It is ideal for padding for stumpwork and creative metal thread embroidery, but also for surface stitch and appliqué.
This is the range of colours I use most for designs such as gardens, hillocks, plants, flowers, skies, rural scenes etc.
Each piece measures 30.5 x 45.7cm. To have a closer look at the felts, either click on the magnifying glass on the main picture, or on the names below.
The colours are:


text:
Jeremy Swayman wins 2nd NHL start, Bruins beat Capitals 4-2
Brad Marchand scored a shorthanded goal, Jeremy Swayman made 31 saves to win his second NHL start and the Boston Bruins beat the Washington Capitals 4-2 on Thursday night.
Jeremy Lauzon, Anton Blidh and Craig Smith also scored for Boston, which won back-to-back starts by its rookie fourth-string goaltender fresh out of college in his first professional season.
"My mindset doesn't change as far as wanting to win and doing whatever I can to help my team win," said Swayman, who made 40 saves in his NHL debut Tuesday at Philadelphia. "The NHL, that's everything and it's a big deal and this team is obviously as good (a) one to be a part of and I'm just enjoying every second I can while I can."
Swayman allowed two power-play goals in under 20 seconds to Alex Ovechkin and T.J. Oshie but kept the Bruins ahead when the Capitals tilted the ice toward him in the second period. The Bruins won consecutive games for the first time since mid-March.
"This is a big week for our team," Marchand said. "This is the time. It's crunch time. We have to continue to separate from the teams below us and we have to build towards the playoffs, regardless of who's in or out of the lineup every night."
Capitals goaltender Ilya Samsonov allowed a leaky goal to Lauzon 33 seconds into the game and was unlucky when defenseman Justin Schultz's attempt to flick the puck off the glass behind the net instead took a fluky bounce to Blidh for a tap-in later in the first period. The goal was Blidh's second in the NHL and first since 2016.
Marchand gave the Bruins a 3-0 lead early in the second period when he deked two Washington defenders and lifted a backhander past Samsonov, who finished with 28 saves.
Despite Ovechkin's 5-on-3 power-play goal that gave him 20 this season and 726 for his career and Oshie's team-leading eighth on the power play, the Capitals couldn't tie it and Smith scored on the power play with 3:05 left in the game.
Washington has lost two in a row and four of its past six.
"We just have to learn from games like this," center Nicklas Backstrom said. "We're playing the top teams in our divisions, too. I think it should be a challenge for us. We should be obviously better, I think. But obviously they are a good team and it's going to be tough games, but we somehow have to turn this around here."
Ovechkin's goal got him to 20 for a 16th consecutive season. It was also his 266th on the power play, breaking a tie with Brett Hull for second on the career list. Ovechkin is eight back of Dave Andreychuk for the most power-play goals in league history.
Swayman is the 146th different goalie Ovechkin has scored on.
"You always dream about facing the greats in the game," Swayman said. "That's a cool thing. But you don't want to get too caught up in it."
Tensions always seem to be high between these teams, and this was their first meeting since Capitals winger Tom Wilson injured Bruins defenseman Brandon Carlo with a hit that landed Wilson a seven-game suspension. Boston's Nick Ritchie and Washington's Garnet Hathaway dropped the gloves late in the first, and there were a combined 13 minor penalties doled out during the game.
Boston was without defenseman Charlie McAvoy for a second consecutive game because of an upper-body injury, and forward Trent Frederic wasn't available because of a non-COVID-19-related illness. Dan Vladar dressed as the backup goaltender with Tuukka Rask injured and Jaroslav Halak on the NHL's COVID-19 protocol list.
Washington's Daniel Carr saw his first NHL action since Feb. 7, replacing Daniel Sprong. Carr was added to the Capitals' roster after Richard Panik cleared waivers and was sent to the taxi squad.
Washington is the only team left in the East Division to not allow some fans into its arena, and one of just three remaining in the U.S. without announced plans for a limited capacity to attend games. Owner Ted Leonsis tweeted this week the organization was "disappointed with the city's failure" to grant a waiver for 10% of capacity at Capital One Arena, which is roughly 1,800 fans.
The Capitals visit the Buffalo Sabres on Friday and the Bruins return to Philadelphia to face the Flyers on Saturday before these teams meet again Sunday in Boston.
Follow AP Hockey Writer Stephen Whyno on Twitter at https://twitter.com/SWhyno
More AP NHL: https://apnews.com/NHL and https://twitter.com/AP_Sports
Sign up for U-T Sports daily newsletter
The latest Padres, Chargers and Aztecs headlines along with the other top San Diego sports stories every morning.
You may occasionally receive promotional content from the San Diego Union-Tribune.