James Reads


Day of Dec 11th, 2019

  • How to Get Americans to Love Capitalism Again

    meta Twitter summary card metadata Open graph metadata Opinion | How to Get Americans to Love Capitalism Again By Bryan Anselm for The New York Times American capitalism is at a serious inflection point. Many Americans, including the two of us, are alarmed by enormous levels of inequality and by declining economic mobility. We are concerned that in many cases American markets are no longer the most competitive in the world. And, we worry that our country’s long-term economic strength will slowly deteriorate because of an unsustainable fiscal trajectory that leaves future generations worse off. The solution is not to upend the system. A market-based economy, for all its flaws, is still the best way to achieve broad economic prosperity and to ensure that living standards continue to rise over time. But the answer is not to maintain the status quo, either. Radical change or complete inaction seem to be the only types of solutions that are being debated in today’s marketplace of ideas. Americans can’t afford to restrict our thinking based on political ideology and the false equivalency of having to pick one extreme or the other. That’s a recipe for stalemate. Since founding the bipartisan Aspen Economic Strategy Group more than two years ago, our focus has been on bringing together leaders with different perspectives to highlight the importance of evidence-based policymaking. Earlier this week, 38 of our members signed on to a statement of principles that should guide the development of a new economic policy agenda. We also believe we must rigorously analyze some of the proposals that are being put forward in today’s policy debates, including universal basic income, “Medicare for all” and direct taxes on wealth. Based on research from the newest book from the Aspen Economic Strategy Group, the two of us are more convinced than ever that those policies are fundamentally misguided and would result in economically harmful outcomes that could put our economy on an unstable and precarious path, harming the very people they are intended to help. The collective work to identify specific policy solutions, however, also suggests to us that there are still many ways to ensure more that many more people can participate in America’s successes. And while there are no silver bullets, nor will there ever be complete agreement about every policy detail, we see many excellent ideas that are ripe for bipartisan collaboration and that can begin the process of adapting our economic policies so that they work for far more people. First, we must aggressively invest in our human capital. That starts with addressing the supply side of the education market, including investments in community colleges to provide more students the option to obtain a high-quality education and complete their degree. This ensures that more American workers have the skills they need to compete in a global economy. Just as important, investing in education will increase economic productivity, which will help drive the wage growth needed to reduce income inequality. There are other steps we can take to further address the distribution of economic opportunity and wage growth. But as Melissa Kearney and Magne Mogstad have argued, universal basic income is not a viable solution. It directs resources away from the neediest individuals and fails to address the underlying factors that contribute to inequality. Instead, we should look at more targeted and efficient approaches to encouraging work by supplementing the wages of low- and middle-income Americans, such as expanding the earned -income tax credit or enacting a wage -subsidy program. Finally, we have to confront the uncomfortable truth that our country is on an unsustainable fiscal trajectory. Spending priorities such as education, infrastructure, and high-value research and development are underfunded, while our commitments to entitlements continue to rise indefinitely. Restoring the sanity of our fiscal position will require raising more revenue, slowing the rate of growth in health care spending, and making Social Security sustainably solvent. Returning to fiscal responsibility through spending reform alone is neither just nor possible. The United States needs to reform its tax code in a manner that is more progressive and produces more revenue. But there are better approaches than a wealth tax, which would be highly distortionary and is unlikely to capture nearly as much revenue as its proponents claim. Making the income tax code more progressive and reforming estate and gift taxes to eliminate the loopholes that allow wealthy Americans to pass on wealth to their children at very low tax rates would be a better first step. Whatever path policymakers choose, it is clear that we need to move away from theoretical arguments and wishful thinking and into the arena of pragmatic policy solutions that can actually be enacted. There is a plethora of policies that already enjoy broad bipartisan support, and these policies can be enacted only through effective government, which will require leaders to engage in principled compromise and make decisions grounded in facts and analyses. The cost of inaction is severe and grows each day, as inequality undermines our economic strength and more Americans become disillusioned with the capitalist system that has made upward mobility a pillar of the country’s identity since its founding. Henry M. Paulson Jr. was the secretary of the Treasury from 2006 to 2009. Erskine Bowles served as co-chairman of the National Commission on Fiscal Responsibility and Reform in 2010. They are co-founders of the Aspen Economic Strategy Group. The Times is committed to publishing a diversity of letters to the editor. We’d like to hear what you think about this or any of our articles. Here are some tips. And here’s our email: letters@nytimes.com. Follow The New York Times Opinion section on Facebook, Twitter (@NYTopinion) and Instagram. Source: How to Get Americans to Love Capitalism Again

    Read at 10:26 pm, Dec 11th

  • Don't call a React function component

    Don't call a React function component The difference between React.createElement and calling a function component directly Watch "Fix 'React Error: Rendered fewer hooks than expected'" on egghead.io I got a great question from Taranveer Bains on my AMA asking: I ran into an issue where if I provided a function that used hooks in its implementation and returned some JSX to the callback for Array.prototype.map. The error I received was React Error: Rendered fewer hooks than expected. Here's a simple reproduction of that error And here's how that behaves when rendered (with an error boundary around it so we don't crash this page): In the console, there are more details in a message like this: 1Warning: React has detected a change in the order of Hooks 2called by BadCounterList. This will lead to bugs and 3errors if not fixed. For more information, read the 4Rules of Hooks: https://fb.me/rules-of-hooks 5 6 Previous render Next render 7 ------------------------------------------------------ 81. useState useState 92. undefined useState 10 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ So what's going on here? Let's dig in. First off, I'll just tell you the solution: 1- <div>{items.map(Counter)}</div> 2+ <div>{items.map(i => <Counter key={i.id} />)}</div> Before you start thinking it has to do with the key prop, let me just tell you it doesn't. But the key prop is important in general and you can learn about that from my other blog post: Understanding React's key prop Here's another way to make this same kind of error happen: The point is that our Example component is calling a hook conditionally, this goes against the rules of hooks and is the reason the eslint-plugin-react-hooks package has a rules-of-hooks rule. You can read more about this limitation from the React docs, but suffice it to say, you need to make sure that the hooks are always called the same number of times for a given component. Ok, but in our first example, we aren't calling hooks conditionally right? So why is this causing a problem for us in this case? Well, let's rewrite our original example slightly: And you'll notice that we're making a function that's just calling another function so let's inline that: Starting to look problematic? You'll notice that we haven't actually changed any behavior. This is just a refactor. But do you notice the problem now? Let me repeat what I said earlier: you need to make sure that the hooks are always called the same number of times for a given component. Based on our refactor, we've come to realize that the "given component" for all our useState calls is not the App and Counter, but the App alone. This is due to the way we're calling our Counter function component. It's not a component at all, but a function. React doesn't know the difference between us calling a function in our JSX and inlining it. So it cannot associate anything to the Counter function, because it's not being rendered like a component. This is why you need to use JSX (or React.createElement) when rendering components rather than simply calling the function. That way, any hooks that are used can be registered with the instance of the component that React creates. So don't call function components. Render them. Oh, and it's notable to mention that sometimes it will "work" to call function components. Like so: But the hooks that are in Counter will be associated with the App component instance, because there is no Counter component instance. So it will "work," but not the way you'd expect and it could behave in unexpected ways as you make changes. So just render it normally. Good luck! You can play around with this in codesandbox: loading relevant upcoming workshops... Source: Don’t call a React function component

    Read at 08:32 pm, Dec 11th

  • Sanders draws line between himself and Warren: A 'capitalist to her bones'

    Vermont Sen. Bernie Sanders sought to differentiate himself from his 2020 rival Sen. Elizabeth Warren, D-Mass., by taking aim at her progressive bonafides during an interview that aired Sunday. Sanders, a self-proclaimed democratic socialist, told ABC's "This Week" that he is the more progressive candidate in the race compared to Warren, who he noted once described herself as a "capitalist to my bones." He added that they have a "somewhat" but "not quite" the same policy outlook. "[E]lizabeth Warren has been a friend of mine for some 25 years," Sanders said. "And I think she is a very, very good senator. But there are differences between Elizabeth and myself. Elizabeth I think, as you know, has said that she is a capitalist through her bones. I’m not. I think the situation today that we face in this country of the greed and the corruption that is existing in Washington, that is existing at the corporate elite level ... I am, I believe, the only candidate who’s gonna say to the ruling class of this country, the corporate elite, enough, enough with your greed and with your corruption. We need real change in this country." Warren, who has surged in recent Democratic primary polling, in 2018 reportedly called herself a "capitalist to my bones" in describing her approach to policy. Sanders, who is trailing Warren in those polls, sought to cast himself as the candidate farthest to the left among the 2020 field having authored the "Medicare for All" legislation that other candidates including Warren have endorsed. "I mean, Elizabeth considers herself, if I got the quote correctly, to be a capitalist to her bones," Sanders said on Sunday. "I don’t. And the reason I am not is because I will not tolerate for one second the kind of greed and corruption and income and wealth inequality and so much suffering that is going on in this country today, which is unnecessary." The two are set to face off Tuesday at a jammed-packed Democratic primary debate in Ohio. Earlier this month, Sanders suffered a heart attack and subsequently left the campaign trail to recover. He has pledged to continue campaigning and said he will participate in the Tuesday debate. Allan Smith Allan Smith is a political reporter for NBC News. Source: Sanders draws line between himself and Warren: A ‘capitalist to her bones’

    Read at 07:42 pm, Dec 11th

  • Fantas, Eel, and Specification 6: Functor

    Fantasy Landers, assemble! We’ve been concatenating for two weeks now; are you ready for something a bit different? Well, good news! If you’re humming, “Oh won’t you take me… to functor town?”, then this is the article for you. Today, friends, we’re going to talk about functors.

    Read at 02:41 pm, Dec 11th

  • Fantas, Eel, and Specification 5: Monoid

    Good Tuesday, Fantasists! This week, we’re going to take a quick(!) look at the semigroup’s older sibling: the monoid. We saw last week that a Semigroup type is one that has some concept of combining values (via concat).

    Read at 02:37 pm, Dec 11th

  • Fantas, Eel, and Specification 4: Semigroup

    Today, after a moment of thanks to all those following this series (seriously, thank you ♥), we can move onto a question that has occupied human thought for aeons: how do we generalise the process of combining (or mooshmashing) things together? With semigroups, of course!

    Read at 02:32 pm, Dec 11th

  • ‘I Got Tired of Hunting Black and Hispanic People’

    Multiple police officers in Brooklyn say they were told by a commander that white and Asian people should be left alone.

    Read at 02:27 pm, Dec 11th

  • Embracing the Universal Web

    There are constantly new features appearing in browsers—from subgrid to variable fonts to better developer tools. It's a really great time to be re-thinking everything we know about design on the web.

    Read at 02:23 pm, Dec 11th

  • Fantas, Eel, and Specification 3.5: Ord

    Honestly, at this rate, the spec is going to grow faster than this blog series… We interrupt our usual schedule to introduce Fantasy Land’s newest member: let’s welcome Ord! Spoiler alert: if you’ve been following this series, this is going to be a pretty easy one.

    Read at 02:21 pm, Dec 11th

  • “Manufacturing Consent” In Action ❧ Current Affairs

    PBS NewsHour does a long update on all the candidates except one. Let us look closely at what happens here. Alcindor begins over a shot of Joe Biden in front of his new “No Malarkey” bus, saying that we have a “Democratic field” in flux, which is true.

    Read at 02:20 pm, Dec 11th

  • Fantas, Eel, and Specification 3: Setoid

    Congratulations! You’ve mastered the fundamentals of daggy, nailed the intro to type signatures, and are ready to begin your journey through Fantasy Land. First stop: the setoid. A setoid is any type with a notion of equivalence.

    Read at 03:26 am, Dec 11th

  • Rezonings Underestimated Development and Displacement in both Williamsburg and Park Slope, Study Shows

    Construction at Greenpoint Landing continues apace, with a second tower rising next to One Blue Slip. Paul Stremple/Bklyner.WILLIAMSBURG/GREENPOINT/PARK SLOPE — Rezoning gentrified the rezoned neighborhoods and displaced communities of color, a new study shows.

    Read at 01:45 am, Dec 11th

  • PHP 7.4 FFI: What you need to know

    Lecture : 6 min. PHP Foreign Function Interface, or FFI for fans, is a PHP extension that allows you to include with ease some externals libraries into your PHP code. That means it’s possible to use C, Go, Rust, etc. shared library directly in PHP without writing a PHP Extension in C.

    Read at 01:36 am, Dec 11th

  • Fantas, Eel, and Specification 2: Type Signatures

    Greetings, traveller. I hope you’ve been having a good one since I posted the first part of this series, and I’d have a read of that before going any further.

    Read at 01:31 am, Dec 11th

Day of Dec 10th, 2019

  • Home For Sale In SLC Mysteriously Missing Driveway

    SALT LAKE CITY, Utah – A Utah man was hoping to sell a Salt Lake City house quickly after fixing it up and installing numerous upgrades over the past three months, but Michael Burns said his plans for the property ran into an unexpected and shocking snag this week. When Burns showed up Sunday to check on the home at 1237 East Hudson Avenue, he noticed what initially looked like a lot of mud on top of the driveway. “Then I got a little closer and I realized our driveway was gone — the whole driveway…gone!” exclaimed Burns of the Burnz Team, which bills itself as a one-stop-shop for selling and buying real estate investing and home loans. “(There was) 75 (feet) by 12 feet just demoed out, just disappeared.” Burns said Monday he never contracted the work and still does not know who excavated the driveway. “I mean, you can see right here, it was professionally done, saw-cut,” Burns said. It apparently wasn’t a fast job, either. “(I) talked to the neighbors across the street and they said, ‘oh yeah, the guys spent two-and-a-half, three days over last weekend pulling it out,” Burns said. He was out of town at the time when the incident occurred. Neighbors apparently couldn’t tell Burns what contractor was working at the property and no surveillance cameras captured the workers on video. Burns said he contacted police, but he said he was told what happened was likely to be viewed as a civil matter. He acknowledged the excavation was probably a mistake and nothing malicious. “I think a construction crew just hit the wrong property and didn’t think they should come back and tell us what they did,” Burns said. He hoped the work crew might see the news coverage of what happened and make it right, given it will take another $10,000 to $12,000 to finish the driveway. “I would come back and say, ‘hey, you know, sorry, what can we do to work it out,’ but that has not happened yet,” Burns said. Source: Home For Sale In SLC Mysteriously Missing Driveway

    Read at 04:31 pm, Dec 10th

  • Real Estate Thought It Was Invincible in New York. It Wasn’t.

    This was the year that New York bit back against big real estate. First, a slate of Democratic candidates declared that they would not take money from real estate developers. They swept into state office last fall, displacing incumbents who were friendly to the industry.

    Read at 03:13 pm, Dec 10th

  • Longtime New York State Sen. Betty Little to retire

    PLATTSBURGH, N.Y. (WCAX) Longtime New York State Sen. Betty Little is calling it quits. She announced on Thursday she will not seek re-election in 2020. Little has represented the North Country in Albany for more than two decades. Our Kelly O'Brien was at the announcement.

    Read at 02:47 pm, Dec 10th

  • Republicans leaving the state Senate

    Life in the minority conference in the state Senate has not been kind to Republicans in the past year. They have lost their majority, their donors and possibly their minds as the Democrats passed one landmark bill after another.

    Read at 02:46 pm, Dec 10th

  • The Problem With ‘Hey Guys’

    A broad coalition of English speakers—teachers, retail workers, ice-cream scoopers, and plenty of others—is grasping for a more inclusive greeting. “Okay, guys,” a female coworker of mine recently began, as she addressed me and a female colleague.

    Read at 02:45 pm, Dec 10th

  • Con Ed on verge of three-year rate hike; prices expected to go up in January

    Get set for a shock in your Con Ed electric and gas bills. Con Ed residential electric rates — already among the nation’s highest — likely will be even higher starting Jan. 1 under a three-year proposal reached by Con Ed, state utility regulators, and customer advocates.

    Read at 02:39 pm, Dec 10th

  • Facebook's Head of AI Says the Field Will Soon ‘Hit the Wall’

    Jerome Pesenti leads the development of artificial intelligence at one of the world’s most influential—and controversial—companies.

    Read at 02:37 pm, Dec 10th

  • George Zimmerman sues family of Trayvon Martin, publisher, prosecutors for $100 million

    George Zimmerman, the neighborhood watch volunteer acquitted of homicide charges in the 2012 fatal shooting of unarmed 17-year-old Trayvon Martin in Sanford, is suing Martin’s family, prosecutors and others involved in the case he claims rested on false evidence, according to a copy of the suit se

    Read at 02:32 pm, Dec 10th

  • The Curious Case Of Joseph Mifsud’s Lost Passport And Wallet

    LONDON — While the world was looking for Joseph Mifsud, the Maltese professor who allegedly delivered word of Hillary Clinton’s stolen emails to Donald Trump's campaign, his passport and wallet sat for 17 months in a lost-and-found office in a Portuguese airport.

    Read at 02:30 pm, Dec 10th

  • Capital in the 21st Century (It Stinks!) — NYC Democratic Socialists

    This month Jack reviews the 2019 documentary, Capital in the 21st Century, directed by Justin Pemberton. If you’re reading this newsletter, odds are you already take a pretty dim view of capital.

    Read at 02:25 pm, Dec 10th

  • Branches — NYC Democratic Socialists

    At their November meeting, the North Brooklyn Branch walked through a brief history and mapped the prison industrial complex, heard from abolitionist organizers, and discussed prison abolition.

    Read at 02:21 pm, Dec 10th

  • Working Groups — NYC Democratic Socialists

    The next Brooklyn Electoral Working Group Meeting will be held on December 4th, 7PM, at Brooklyn Game Lab, 310 7th Avenue in Park Slope. After becoming a citywide priority campaign, the Ecosocialist Working Group’s Public Power Campaign campaign continues to build momentum.

    Read at 02:20 pm, Dec 10th

  • Manipulating AST with JavaScript

    Previously, I’ve talked about how to write a babel transformation, and I went one step deeper into Babel, by , I demonstrated how Babel parses your code into AST, transforms it and generates back into code.

    Read at 02:19 pm, Dec 10th

  • Paweł Komarnicki

    Hello! What's your background and what do you do? While I received my formal Computer Science degree from Wroclaw University of Science and Technology in 2010, I was one of the “nerdy kids” of the 90’s that wanted to change the world with technology and computers.

    Read at 02:16 pm, Dec 10th

  • Typed Properties in PHP 7.4 - 7.4 • PHP.Watch

    Typed Properties in PHP 7.4 PHP 7.4 finally brings typed properties. This is a feature I have been looking forward, and I have been spending some quality time working on my existing projects to add support for typed properties. With typed properties, you can set a type for all class properties. When a type is set, PHP engine prevents anyone from setting a different type to the class property. class Example { public string $name; public DateTime $birthday; } The snippet above will make sure that Example::$birthday property will always be a DateTime object. Prior to PHP 7.4, this sort of strict data patterns would have required to have setBirthDate(DateTime $birthdate): void and getBirthDate(): DateTime methods to enforce the data integrity. Supported property types Types supported for class properties. Scalar types: int, string, bool, and float. Compound types: array, iterable and object. Any class or interface name (such as DateTime, FooBar) and stdClass. References to parent and own objects: self and parent. Types not supported for class properties void: Having a void property wouldn't make sense. callable: Not supported because its behavior is unpredictable. Take a look at consistent callables RFC for more background. This basically becomes troublesome when callables can be declared with array syntax, e.g. as [$this, 'buildForm']. The uninitialized state This will be where most of the hair pulling might occur. With PHP 7.4 typed properties, class properties have an uninitialized state. This simply means that the property is not initialized yet. This is not the same as null.. If there is no type is declared, properties have null as their uninitialized value: class Example { public $name; } $foo = new Example(); var_dump($foo->name === null); // true When a type is declared, all properties will have an uninitialized state. It is not allowed to access class properties prior to assigning an explicit value. class Example { public string $name; } $foo = new Example(); var_dump($foo->name === null); In this snippet, the $name property is uninitialized. This is not the same as null, and the snippet above will throw an error: Fatal error: Uncaught Error: Typed property Example::$name must not be accessed before initialization in ... Check uninitialized state You can check if a class property is uninitialized using isset($foo->name). Because this value is not the same as null, you cannot use $foo->name === null to check if the property is uninitialized. Reset property to uninitialized state To reset a property back to its uninitialized state, use unset($foo->name). Once unset, trying to access the property without assigning it a value will throw the same Typed property ... must not be accessed before initialization ... error. Nullable types Similar to PHP 7.1's nullable types, property types can be marked nullable as well. To mark a property can be null, prefix its type with a question mark, e.g: ?string. class Example { public ?string $name; } $foo = new Example(); $foo->name = 'Ayesh'; // Valid $foo->name = null; // Valid Even if a property is marked nullable, its uninitialized value will not be null. For example, the snippet below will still throw an error: class Example { public ?string $name; } $foo = new Example(); var_dump($foo->name); // Fatal error: Uncaught Error: Typed property Example::$name must not be accessed before initialization While this can appear cumbersome to work with, this provides a brilliant feature that you can be certain that the class property will always be of that type. If the value is not initialized, PHP will give up and throw an error instead of returning null, as it would for untyped properties. Strict types Class properties also support the strict type declaration with declare(strict_types=1) at the top of the file's PHP block. Without strict types, PHP will cast the values to the property type. class Example { public string $name; } $foo = new Example(); $foo->name = 420; var_dump($foo->name); // string(3) "420" Notice how we set an integer to the string property, and var_dump() call returns "420" as a string. When assigning the value, the engine casts the value to the declared type. To minimize the problems with type juggling and to take the full benefits of typed properties, I recommend that you test your classes with declare(strict_types=1). It is easy to overlook when PHP is being helpful when it casts to a type for you, but this can be the root of some bug downstream. It's easier to debug an error that pops up immediately than a bug that only happens on Friday evenings at 6:28PM, only when DST is in effect. Static properties and references Static properties can have types declared too. This may seem like an obvious detail, but the former proposals for typed properties did not include static properties. In PHP 7.4, you can declare types for static properties too. Furthermore, you can return a reference to a typed property, and the types will be still honored: class Example { public string $name; } $foo = new Example(); $foo->name = 'Apple'; $bar =& $foo->name; $bar = []; // Not allowed This will throw an error: Fatal error: Uncaught TypeError: Cannot assign ... to reference held by property Example::$name of type ... in ... Default values in constructors and property declaration For historical reasons, PHP allows you to set a default value for function arguments in its declaration even if the type is not nullable. class Example { public function __construct(string $name = null) { var_dump($name); } } $foo = new Example(); // NULL In the constructor, we explicitly mark that the $name argument is not nullable, and yet PHP accepts null as the default value. This behavior only applies to null default values. Although this is semantically invalid, this behavior is allowed for historical and implementation reasons. With typed properties, this is not allowed: class Example { private string $name = null; } $foo = new Example(); // NULL This will promptly throw an error: Fatal error: Default value for property of type ... may not be null. Use the nullable type ?... to allow null default value in ... Type Variance PHP 7.4 comes with return type variance, which means a child class can return a more specific instance. This is not yet supported for property types. For example: class A {} class B extends A {} class Fruits { public B $foo; } class Banana extends Fruits { public A $foo; } Code above would not work. Although B is a subset of A class, changing the type declaration of Banana::$foo is not allowed. You can still assign an instance of A to Banana::$foo. This is called covariance, and it is now supported for return types. Trying the above will throw an error like the following: Fatal error: Type of Banana::$foo must be B (as in class Fruits) in W:localhosttesttest.php on line 11 The following code is still valid: class A {} class B extends A {} class Fruits { public A $foo; } class Banana extends Fruits { public A $foo; } $banana = new Banana(); $banana->foo = new B(); Notice how the property declaration in Fruits::$foo and Banana::$foo is A, but we assign an instance B to it. To summarize: You cannot substitute a child class for the property. You cannot add types to child classes if the parent does not have types enforced. You cannot mark a non-nullable type as nullable in a child class. You cannot mark a nullable type as non-nullable in a child class. To visualize this, take a look at the following inheritance chain. None of the following are allowed: class A {} class B extends A{} class Fruits { public $no_type; public A $strict_type; public ?string $nullable; public string $non_nullable; } class Banana extends Fruits { public A $no_type; // Not allowed to add types in a subclass. public $strict_type; // Not allowed to remove type in a childclass. public string $nullable; // Not allowed to make non-nullable public ?string $non_nullable; // Not allowed to make nullable } Above will throw the following errors (not at the same time): Fatal error: Type of Banana::$no_type must not be defined (as in class Fruits) in ... on line ... Fatal error: Type of Banana::$strict_type must be A (as in class Fruits) in ... on line 17 Fatal error: Type of Banana::$nullable must be ?string (as in class Fruits) in ... on line 17 Fatal error: Type of Banana::$non_nullable must be string (as in class Fruits) in ... on line 17 Backwards compatibility Declaring property types is optional, and all your existing code should work. If you plan to upgrade an existing code base to typed properties, keep an eye on the uninitialized state, and inheritance where rules are enforced rather strictly. Further, property types do not carry the legacy behavior of allowing null values in their function/method arguments, and it can come as a surprise. Final Thoughts Property types is a feature that I was personally excited about, and now that it's finally here, I have spent some time adding property types to my existing private projects. PHPStorm 2019.3 comes with support for all PHP 7.4 features, and there is a quick-fix to add property types if it can be gathered from property docblock comments or from the constructor. Even in projects that had 100% test coverage, I discovered a few bugs that were there all the time, but property types brought them front and center! Open source projects might take some time to require PHP 7.4 as the minimum version, but it wouldn't prevent you from using them in your private projects. RFC Externals.io discussion Implementation Source: Typed Properties in PHP 7.4 – 7.4 • PHP.Watch

    Read at 02:03 pm, Dec 10th

  • Fantas, Eel, and Specification · Tom Harding

    Fantas, Eel, and Specification A series of posts written to explore and explain the Fantasy Land JavaScript specification, and to introduce some concepts of functional programming.

    Read at 05:16 am, Dec 10th

  • Fantas, Eel, and Specification 1: Daggy

    Hello again, the Internet! As a functional programming zealot* and JavaScript developer†, I spend a lot of my time raving about their crossover. In this series, we’ll look at the Fantasy Land spec in its entirety, and go through examples of how we can use the typeclasses within it.

    Read at 05:15 am, Dec 10th

  • 90,000 Packages Disappear Daily in N.Y.C. Is Help on the Way?

    Package theft has also soared in cities like Denver and Washington. The increase has frustrated shoppers and led to creative measures for thwarting thieves.

    Read at 05:10 am, Dec 10th

  • The SPD Turns Left

    It would be hard to overestimate the significance of this weekend’s results for German politics. A relatively unknown left-wing duo has triumphed in a one member one vote election for the leadership of the Social Democratic Party (SPD), the country’s oldest party.

    Read at 04:23 am, Dec 10th

Day of Dec 9th, 2019

  • No Shortcuts, but to where?

    Nick Driedger reviews Jane McAlevey’s No Shortcuts: Organizing for Power in the New Gilded Age. There is an unwritten rule on the left: you only criticize people with a larger following than you, who have more of a base than you have, who take up more space close to the mainstream than you do.

    Read at 11:33 pm, Dec 9th

  • Democrats’ Plan Will Suppress Third Parties in New York

    The move, which takes aim at the Working Families Party, was met by angry responses when announced. “Shame!” one person shouted. ALBANY, N.Y. — For years, Gov. Andrew M.

    Read at 11:23 pm, Dec 9th

  • An Engineering Team where Everyone is a Leader

    Having worked for a decade as an engineer at various companies, I noticed how most teams in software often have "the" manager and "the" tech lead or "the" senior engineer. These are the decision-makers and ones that lead all projects.

    Read at 11:20 pm, Dec 9th

  • The X-ing of Language: The Case AGAINST ‘Latinx’

    Man/Woman/X is born free, and everywhere his/her/their language is in chains. In the name of inclusivity, during the course of the last half century the English language has slowly and surely been bulldozed and paved over.

    Read at 11:08 pm, Dec 9th

  • John Bolton is My Hero? Or, Don't Knock Impeachment - Democratic Socialists of America (DSA)

    John Bolton is My Hero? Or, Don’t Knock Impeachment November 21, 2019 by Max Sawicky Many comrades have trouble getting their arms around the removal of the most depraved, reactionary president in memory. Not surprisingly, nobody in their right mind wants to launch a new Cold War against the Satanic Russians. Nevertheless, heartfelt encouragement of impeachment from the Left is fully warranted. As the impeachment process struggles to be born, Democrats in Congress are cautiously constructing a case against the president on the narrowest grounds available – his attempt to extort the government of Ukraine to assist his 2020 re-election campaign. It has not mattered that Donald Trump manifested his crookedness from day one, not to mention earlier. As one pundit noted, New York area elites have a lot to answer for, in failing to restrain this creature decades ago. His racist rhetoric, his vicious assault on immigrants, his indulgence of violence-prone right-wing street goons, his blatant attempts to obstruct justice, his myriad acts of garden-variety graft, none of this was enough to jump-start impeachment. We have a lot to be bitter about. It’s turning out that the Democrats are impeaching Trump for being a bad Republican, for betraying the conservative principles of Ronald Reagan, the Bushes, and their foreign policy attack dog, John Bolton. Nevertheless, we are where we are. Democrats have Trump dead to rights on Ukraine. A vote to impeach in the House of Representatives is likely. Democratic Speaker-of-the-House Nancy Pelosi is not known for calling votes she will lose. On the Senate side, of course a vote to remove Trump is unlikely. However, a weekly ventilation of evidence over the next six months cannot but have a salutary political impact on public opinion and on Democratic prospects in 2020. Recent Democratic electoral victories in Virginia and less likely places like Louisiana are encouraging in this regard. One dubious objection is that failure of the Senate to remove Trump would enable him to claim vindication. As we speak, the president is shoveling money to Republican incumbent senators in danger of defeat next year. The legitimacy of their votes to keep him in office is vulnerable to derision. Trump’s burgeoning record of dishonesty increasingly diminishes the veracity of claims he will make between now and next November. Another objection is that removal would give us President Pence. Of course, if the Senate doesn’t vote to remove, there will never be a President Pence. If it does, however, the ensuing intra-Republican bloodletting would cripple the party for several electoral cycles. Resentment of Pence and any traitors by Trump’s core deplorable voters would lead to a Democratic tidal wave of victories in 2020. Odds are that an embittered, vengeful Trump would facilitate it. In criminal proceedings, it is common for lawyers to impugn the credibility of witnesses or defendants by reference to acts outside whatever offense is in question. Sometimes this is legal and sometimes it isn’t. The relevance is that while the House Democrats are pursuing a political project – impeachment – on the narrowest of grounds, no such scruples restrain the Left. A full-spectrum assault on the Republican Party’s depredations over the past three years, under the leadership of their poster boy, Donald Trump, facilitates impeachment in the same way aspersions on a defendant’s character reduce his or her standing in the eyes of the jury. In court this can be unfair; in politics, it is fair. It also supplies much-needed progressive context to the proceedings. The specifics of the Ukraine affair should not be off-putting on the Left. Whatever you think of the U.S./EU aligned government of Ukraine, itself chock-full of dubious characters, there is no good reason to favor Russian aggression against it. Nor is criticism of Russia really redolent of Cold War hysteria. Russia is no longer Soviet or Red. Arguably, it has drifted quite far from any such station. It is merely one of the larger autocratic adversaries of the U.S. Foregoing any sympathy for its conflicts with less-powerful, neighboring countries is no indulgence of U.S. imperialism. So impeachment can be fun. Others may take different sorts of satisfaction with it, but our own interests can be furthered as well. Democratic Party victories open up space for challenges to incumbents from the left. It’s easier to consider a progressive challenger when the potential Republican alternatives have little hope of benefitting. A higher margin of D votes in Congress, as well as possession of the White House, puts a greater obligation on the party establishment to produce results for the working class. Instead of being embroiled in arguments with ridiculous Trumpist loons, we can look forward to more serious debate with Democratic centrists on neoliberalism vs. democratic socialism. The alternative to progressive engagement in the impeachment drama is progressive invisibility, just as public opinion is moving left and crying for change and leadership. It doesn’t pay to get too far ahead of where the heads of most people are at. Back in the day, at a certain point the anti-war movement that the Left had done so much to germinate became mainstream. Some radicals became bored when everybody started agreeing with them. It was no longer cool. They moved on to more distant concerns. That was a mistake. /sidebar Source: John Bolton is My Hero? Or, Don’t Knock Impeachment – Democratic Socialists of America (DSA)

    Read at 10:50 pm, Dec 9th

  • The most copied StackOverflow snippet of all time is flawed! | Programming.Guide

    The most copied StackOverflow snippet of all time is flawed! by Andreas Lundblad, 2019-12-02 In a recent study titled Usage and Attribution of Stack Overflow Code Snippets in GitHub Projects, an answer I wrote almost a decade ago was found to be the most copied snippet on Stack Overflow. Ironically it happens to be buggy. A Long Long Time Ago… Back in 2010 I was sitting in my office and doing what I wasn’t supposed to be doing: code golfing and chasing reputation on Stack Overflow. The following question got my attention: How do you print a byte count in a human readable format? That is, how do you format something like 123,456,789 bytes as “123.5 MB”. The implicit spec here is that the resulting string should have a value between 1 and 999.9 followed by a suffix with an appropriate magnitude. One answer had already been posted. The code in that answer was based on a loop. The idea was simple: Try all magnitudes, going from the largest (EB = 1018 bytes) down to the smallest (B = 1 byte) and use the first one that is smaller than the number of bytes. In pseudo code it looks something like this: suffixes = [ "EB", "PB", "TB", "GB", "MB", "kB", "B" ] magnitudes = [ 1018, 1015, 1012, 109, 106, 103, 100 ] i = 0 while (i < magnitudes.length && magnitudes[i] > byteCount) i++ printf("%.1f %s", byteCount / magnitudes[i], suffixes[i]) Usually when there’s a correct answer posted that already has a positive score, it’s hard to catch up with it. In Stack Overflow lingo it’s referred to as the Fastest Gun in the West Problem. In this case the existing answer had a few flaws, so I still saw an opportunity to top it. At the very least, the loop based code could be cleaned up significantly. This is Algebra, I know this! Then it hit me. The kB, MB, GB, … suffixes are nothing but powers of 1000 (or 1024 in IEC standard) which means it should be possible to compute the right suffix using logarithms instead of a loop. Based on this idea, I posted the following: public static String humanReadableByteCount(long bytes, boolean si) { int unit = si ? 1000 : 1024; if (bytes < unit) return bytes + " B"; int exp = (int) (Math.log(bytes) / Math.log(unit)); String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp-1) + (si ? "" : "i"); return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre); } Granted it’s not very readable and log / pow probably makes it less efficient than other solutions. But there were no loops and almost no branching which I thought was pretty neat. The math behind this is straight forward. The byte count is expressed as byteCount = 1000s where s represents the scale. (For binary notation, base 1024 is used.) Solving for s gives s = log1000(byteCount). There’s no log1000 readily available in the API, but we can express it in terms of the natural logarithm as follows s = log(byteCount) / log(1000). We then floor s (cast to int) since if we for example have more than one megabyte (but not a full gigabyte) we want to use MB as magnitude. At this point if s = 1 the scale is kilobytes, if s = 2 the scale is megabytes, and so on. We divide the byteCount with 1000s and slap on the corresponding letter prefix. All I could do now was to wait and see if the community would appreciate the answer. Little did I know that this would become the most copied snippet on Stack Overflow. A Study on Attribution Fast forward to 2018. A PhD student by the name Sebastian Baltes publishes a paper in the journal of Empirical Software Engineering. The title is Usage and Attribution of Stack Overflow Code Snippets in GitHub Projects and it basically tries to answer one question: Is Stack Overflow’s CC BY-SA 3.0 license respected? I.e. to what extent is proper attribution given, when copying code from Stack Overflow. As part of their analysis they extracted code snippets from the Stack Overflow data dump and matched them against code from public GitHub repos. Quoting the abstract: We present results of a large-scale empiricalstudy analyzing the usage and attribution of non-trivial Java code snippetsfrom SO answers in public GitHub (GH) projects. (Spoiler alert: No, most people do not include proper attribution.) In the paper, they include the following table: That answer at the top with id 3758880 happens to be the answer I had posted eight years earlier. At this point the answer had over a hundreds of thousands of views and over a thousand upvotes. A quick search on GitHub indeed shows thousands of occurrences of humanReadableByteCount. To check if you happen to have the code in a locally checked out repo: $ git grep humanReadableByteCount Fun side story: How did I first hear about this study? Sebastian had found a match in the OpenJDK repository. There was no attribution and the OpenJDK license is not compatible with CC BY-SA 3.0. He reached out to the dev mailing list asking if the code on Stack Overflow was copied from OpenJDK, or if it was the other way around. The funny part here is that I used to work at Oracle, on the OpenJDK project, so a former colleague and friend of mine replied with the following: Hi, why not ask the author of this SO post (aioobe) directly? He is an OpenJDK contributor and was employed by Oracle at the time this code appeared in the OpenJDK source repos. /Claes Oracle doesn’t take these things lightly. I happen to know that some people at Oracle took a sigh of relief when they read this reply, and saw it as a bit of a triumph after the “accusation”. Sebastian then reached out to me to straighten it out, which I did: I had not yet started at Oracle when that commit was merged, and I did not contribute that patch. Jokes on Oracle. Shortly after an issue was filed and the code was removed. The Bug I bet you’ve already given it some thought. What is that bug in the code snippet? Here it is again: public static String humanReadableByteCount(long bytes, boolean si) { int unit = si ? 1000 : 1024; if (bytes < unit) return bytes + " B"; int exp = (int) (Math.log(bytes) / Math.log(unit)); String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp-1) + (si ? "" : "i"); return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre); } After exabytes, 1018, comes zettabytes, 1021. Could it be that a really large input causes an index out of bounds on the "kMGTPE" string? Nope. The maximum long value is 263 - 1 ≈ 9.2 × 1018, so no long value will ever go beyond EB. Could it be a mix-up between SI and binary? Nope. There was a mix-up in an early version of the answer, but that was fixed rather quickly. Can exp end up being 0 causing charAt(exp-1) to fail? Nope. The first if-statement covers that case. The exp value will always be at least 1. Could there be some weird rounding error in the output? Now we’re getting there… Lots of 9’s The solution works all the way up until it approaches 1 MB. When given 999,999 bytes as input, the result (in SI mode) is "1000.0 kB". While it is true that 999,999 is closer to 1,000 × 10001 than it is to 999.9 × 10001, the 1,000 “significand” is out of range according to spec. The correct result is "1.0 MB". FWIW, all 22 answers posted, including the ones using Apache Commons and Android libraries, had this bug (or a variation of it) at the time of writing. So how do we fix this? First of all, we note that the exponent (exp) should change from ‘k’ to ‘M’ as soon as the number of bytes is closer to 1 × 1,0002 (1 MB) than it is to 999.9 × 10001 (999.9 k). This happens at 999,950. Similarly, we should switch from ‘M’ to ‘G’ when we pass 999,950,000 and so on. To achieve this we calculate this threshold and bump exp if bytes is larger: if (bytes >= Math.pow(unit, exp) * (unit - 0.05)) exp++; With this change the code works well all the way up until the byte count approaches 1 EB. Even More 9’s Given the input 999,949,999,999,999,999 the result is now 1000.0 PB while correct result is 999.9 PB. Mathematically the code is accurate, so what’s going on here? At this point we’re running into the precision limitations of a double. Floating Point Arithmetic 101 Due to the IEEE 754 representation floating point values close to zero are very dense, and large values are very sparse. In fact, half of all values are found between −1 and 1, and when talking large doubles, a value as large as Long.MAX_VALUE means nothing. Literally. double l1 = Double.MAX_VALUE; double l2 = l1 - Long.MAX_VALUE; System.err.println(l1 == l2); See Bits of a Floating Point Value for a deep dive. There are two problematic computations: The division in the String.format argument, and The threshold for bumping exp. We could switch to BigDecimal, but where’s the fun in that?! Besides, it gets messy anyway because there’s no BigDecimal log function in the standard API. Scaling down intermediate values For the first issue we can scale down the bytes value to a range where the the precision is better, and adjust exp accordingly. The end result is rounded off anyway, so it doesn’t matter that we’re throwing out the least significant digits. if (exp > 4) { bytes /= unit; exp--; } Adjusting the least significant bits For the second issue, we do care about the least significant bits (999,949,99…9 and 999,950,00…0 should end up with different exponents) so this issue calls for a different solution. First we note that there are 12 different possible values for the threshold (6 for each mode), and only one of them ends up faulty. The faulty result can be uniquely identified by the fact that it ends with D0016. If this is the case we simply adjust it to the correct value. long th = (long) (Math.pow(unit, exp) * (unit - 0.05)); if (exp < 6 && bytes >= th - ((th & 0xFFF) == 0xD00 ? 52 : 0)) exp++; Since we rely on specific bit patterns in floating-point results, we slap on strictfp to ensure it works regardless of the hardware running the code. Negative input It’s unclear under what circumstances a negative byte count could be relevant, but since Java doesn’t have unsigned long, we better deal with it. Right now an input such as −10,000 results in -10000 B. Let’s introduce absBytes: long absBytes = bytes == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(bytes); The complicated expression is due to the fact that -Long.MIN_VALUE == Long.MIN_VALUE. Now we perform all computations related to exp using absBytes instead of bytes. Final Version Here’s the final version of the code, golfed and compacted in the spirit of the original version: public static strictfp String humanReadableByteCount(long bytes, boolean si) { int unit = si ? 1000 : 1024; long absBytes = bytes == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(bytes); if (absBytes < unit) return bytes + " B"; int exp = (int) (Math.log(absBytes) / Math.log(unit)); long th = (long) (Math.pow(unit, exp) * (unit - 0.05)); if (exp < 6 && absBytes >= th - ((th & 0xfff) == 0xd00 ? 52 : 0)) exp++; String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i"); if (exp > 4) { bytes /= unit; exp -= 1; } return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre); } Note that this started out as a challenge to avoid loops and excessive branching. After ironing out all corner cases the code is even less readable than the original version. Personally I would not copy this snippet into production code. For updated code that is of production quality see separate article: Formatting byte size to human readable format Key Takeaways Stack Overflow snippets can be buggy, even if they have thousands of upvotes. Test all edge cases, especially for code copied from Stack Overflow. Floating-point arithmetic is hard. Do include proper attribution when copying code. Someone might just call you out on it. Comments (11) Whoa! What a writeup. Thanks for sharing by Nick |  Reply This is a really hard problem. by Ssuching |  Reply Brilliant. Attitude too. Thanks a lot. by syjmick |  Reply I think key takeaway here is: prefer short and simple loops over math. As you already said, the math is very hard to get exactly right (so, error prone and hard to read). But I believe it is also at least an order of magnitude slower than the loop-based solution. Did you run any benchmarks? by Ivan |  Reply In general I agree with you. In this particular case however, one should note that the rounding error, negative input, and floating-point precision problems would apply also to a simple loop solution. I have not done any benchmarking. Would be interesting for sure. by Andreas Lundblad |  Reply This is fantastically done. Thanks for posting this. by John Doe |  Reply This is very interesting article, I worked with floating point but always had difficulty to grasp the special cases of rounding. This article is good academic view of special cases to consider. Thanks! Five stars for this article. ★★★★★ by Audiory |  Reply This article was quite a journey! Thanks :) by swiatek7 |  Reply Awesome! Thanks for sharing! by Adam |  Reply Nice article, thanks for sharing this story! So, how is it done in Unix? Some commands like ls, df have the -h human readable option. by IvanV |  Reply The implementation for coreutils is found in human.c by Andreas Lundblad |  Reply Add comment Source: The most copied StackOverflow snippet of all time is flawed! | Programming.Guide

    Read at 10:23 pm, Dec 9th

  • The Problems of "Schema-First" GraphQL Server Development | Prisma

    Overview: From schema-first to code-first This article gives an overview of the current state of the GraphQL server development space. Here's a quick outline of what is covered: What does "schema-first" mean in this article? The evolution of GraphQL server development Analyzing the problems of SDL-first development Conclusion: SDL-first could potentially work, but requires a myriad of tools Code-first: A language-idiomatic way for GraphQL server development While this article mostly gives examples of the JavaScript ecosystem, much of it applies to GraphQL server development in other language ecosystems as well. What does "schema-first" mean in this article? The term schema-first is quite ambiguous and in general conveys a very positive idea: Making schema design a priority in the development process. Thinking about the schema (and therefore the API) before implementing it typically results in better API design. If schema design falls short, there's a risk of ending up with an API that's an outcome of how the backend is implemented, ignoring the primitives of the business domain and needs of API consumers. In this article, we’re going to discuss the drawbacks of a development process where the GraphQL schema is first defined manually in SDL, with the resolvers implemented afterwards. In this methodology, the SDL is the source of truth for the API. To clarify the distinction between schema-first design and this specific implementation approach, we'll refer to it as SDL-first from here on. In contrast, code-first (also sometimes called resolver-first) is a process where the GraphQL schema is implemented programmatically and the SDL version of the schema is a generated artifact of that. With code-first, you can still pay a lot of attention to upfront schema design! The evolution of GraphQL server development When GraphQL was released in 2015, the tooling ecosystem was scarce. There was only the official specification and its reference implementation in JavaScript: graphql-js. Until today, graphql-js is used in the most popular GraphQL servers, like apollo-server, express-graphql, and graphql-yoga. When using graphql-js to build a GraphQL server, the GraphQL schema is defined as a plain JavaScript object: As can be seen from these examples, the API for creating GraphQL schemas with graphql-js is very verbose. The SDL representation of the schema is a lot more concise and easier to grasp: type Query { hello(name: String): String } Learn more about building GraphQL schemas with graphql-js in this article. Phase 2: Schema-first popularized by graphql-tools To ease development and increase the visibility into the actual API definition, Apollo started building the graphql-tools library in March 2016 (here's the first commit). The goal was to separate the schema definition from the actual implementation, this led to the currently popular schema-driven or schema-first / SDL-first development process: Manually write the GraphQL schema definition in GraphQL SDL Implement the required resolver functions With this approach, the examples from above now look like this: These code snippets are 100% equivalent to the code above that uses graphql-js, except they're a lot more readable and easier to understand. Readability is not the only advantage of SDL-first: The approach is easy to understand and great for building things quickly As every new API operation first needs to be manifested in the schema definition, GraphQL schema design is not an after-thought The schema definition can serve as API documentation The schema definition can serve as a communication tool between frontend and backend teams — frontend developers are getting empowered and more involved in the API design The schema definition enables quick mocking of an API Phase 3: Developing new tools to "fix" SDL-first While SDL-first has many advantages, the last two years have shown that it's challenging to scale it to larger projects. There are a number of problems that arise in more complex environments (we'll discuss these in detail in the next section). The problems, by themselves, are indeed mostly solvable — the actual problem is that solving them requires using (and learning) many additional tools. During the past two years, a myriad of tools have been released that are trying to improve the workflows around SDL-first development: from editor plugins, to CLIs to language libraries. The overhead in learning, managing, and integrating all these tools slows developers down, and makes it difficult to keep up with the GraphQL ecosystem. Analyzing the problems of SDL-first development Let's now dive a bit deeper into the problem areas around SDL-first development. Note that most of these issues particularly apply to the current JavaScript ecosystem. Problem 1: Inconsistencies between schema definition and resolvers With SDL-first, the schema definition must match the exact structure of the resolver implementation. This means developers need to ensure that the schema definition is in sync with the resolvers at all times! While this is already a challenge even for small schemas, it becomes practically impossible as schemas grow to hundreds or thousands of lines (for reference, the GitHub GraphQL schema has more than 10k lines). Tools/Solution: There are a few tools that help keeping schema definition and resolvers in sync. For example, through code generation with libraries like graphqlgen or graphql-code-generator. Don't think this is an issue? Take our quiz from the graphqlgen article. Problem 2: Modularization of GraphQL schemas When writing large GraphQL schemas, you typically don't want all of your GraphQL type definitions to reside in the same file. Instead, you want to split them up into smaller parts (e.g. according to features or products). Tools/Solution: Tools like graphql-import or the more recent graphql-modules library help with this. graphql-import uses a custom import syntax written as SDL comments. graphql-modules is a toolset to help with schema separation, resolver composition, and the implementation of a scalable structure for GraphQL servers. Problem 3: Redundancy in schema definitions (code reuse) Another question is how to reuse SDL definitions. A common example for this issue are Relay-style connections. While providing a powerful approach to implement pagination, they require a lot of boilerplate and repeated code. There's currently no tooling that helps with this issue. Developers can write custom tools to reduce the need for repeating code, but the problem lacks a generic solution at the moment. Problem 4: IDE support & developer experience The GraphQL schema is based on a strong type system which can be a tremendous benefit during development because it allows for static analysis of your code. Unfortunately, SDL is typically represented as plain strings in your programs, meaning the tooling doesn't recognize any structure inside of it. The question then becomes how to leverage the GraphQL types in your editor workflows to benefit from features like auto-completion and build-time error checks for your SDL code. Tools/Solution: The graphql-tag library exposes the gql function that turns a GraphQL string into an AST and therefore enables static analysis and the features following from that. Aside from that, there are various editor plugins, such as the GraphQL or Apollo GraphQL plugins for VS Code. Problem 5: Composing GraphQL schemas The idea of modularizing schemas also leads to another question: How to compose a number of existing (and distributed) schemas into a single schema. Tools/Solution: The most popular approach for schema composition has been schema stitching which is also part of the aforementioned graphql-tools library. To have more control over how exactly the schema is composed, you can also use schema delegation (which is a subset of schema stitching) directly. Conclusion: SDL-first could potentially work, but requires a myriad of tools After having explored the problem areas and various tools developed to solve them, it seems like that SDL-first development could work eventually – but also that it requires developers to learn and use a myriad of additional tools. Workarounds, workarounds, workarounds, ... At Prisma, we played a major role in pushing the GraphQL ecosystem forward. Many of the mentioned tools have been built by our engineers and community members. After several months of development and close interactions with the GraphQL community, we've come to realize that we're only fixing symptoms. It's like fighting a Hydra – solving one problem leads to several new ones. Ecosystem lock-in: Buying into an entire toolchain We really appreciate the work of our friends at Apollo who constantly work on improving the development workflows around SDL-first development. Another popular example for building GraphQL servers in a SDL-first way is AWS AppSync. It diverges a bit from the Apollo model since resolvers are (typically) not implemented programmatically but auto-generated from the schema definition. While the community greatly benefits from so many tools, there's a risk of ecosystem lock-in for developers when they need to take a full bet on the toolchain of a certain organization. The real solution probably would be to bake many of the SDL-first opinions into the GraphQL core itself – which is unlikely to happen in the foreseeable future. SDL-first disregards individual characteristics of programming languages Another problematic aspect of SDL-first is that it disregards the individual features of a programming language by imposing similar principles, no matter which programming language is used. Code-first approaches work really well in other languages: the Scala library sangria-graphql leverages Scala's powerful type system to elegantly build GraphQL schemas, graphlq-ruby uses many of the awesome DSL features of the Ruby language. Code-first: A language-idiomatic way for GraphQL server development The only tool you need is your programming language Most of the SDL-first problems come from the fact that we need to map the manually written SDL schema to a programming language. This mapping is what causes the need for additional tools. If we follow the SDL-first path, the required tools will need to be reinvented for every language ecosystem, and look differently for each one as well. Instead of increasing the complexity of GraphQL server development with more tools, we should strive for a simpler development model. Ideally one, that lets developers leverage the programming language they're already using – this is the idea of code-first. What exactly is code-first? Remember the initial example of defining a schema in graphql-js? This is the essence of what code-first means. There is no manually maintained version of your schema definition, instead the SDL is generated from the code that implements the schema. While the API of graphql-js is very verbose, there are many popular frameworks in other languages that work based on the code-first approach, such as the already mentioned graphlq-ruby sangria-graphql, as well as graphene for Python or absinthe-graphql for Elixir. Code-first in practice While this article is mostly about understanding the issues of SDL-first, here's a little teaser for what building a GraphQL schema with a code-first framework looks like: const Query = objectType('Query', t => { t.string('hello', { args: { name: stringArg() }, resolve: (_, { name }) => `Hello ${name || `World`}!`, }) }) const schema = makeSchema({ types: [Query], outputs: { schema: './schema.graphql'), typegen: './typegen.ts', }, }) Wtih this approach, you define your GraphQL types directly in TypeScript/JavaScript. With the right setup and thanks to intelligent code completion, your editors will be able suggest the available GraphQL types, fields and arguments as you define them. A typical editor workflow includes a development server running in the background that regenerates typings whenever files are saved. Once all GraphQL types are defined, they're passed into a function to create a GraphQLSchema instance which can be used in your GraphQL server. By specifying the ouputs, you can define where the generated SDL and typings should be located. The next parts of this article series will discuss code-first development in more detail. Getting the benefits of SDL-first, without needing all the tools Earlier we enumerated the benefits of SDL-first development. In fact, there's no need to compromise on most of them when using the code-first approach. The most important benefit of using the GraphQL schema as a crucial communication tool for frontend and backend teams remains. Looking at the GitHub GraphQL API as an example: GitHub uses Ruby and a code-first approach to implement their API. The SDL schema definition is generated based on the code that implements the API. However, the schema definition is still checked into version control. This makes it incredibly easy to track changes to the API during the development process and improves the communication between various teams. Other benefits like API documentation or empowering frontend developers don't get lost with code-first approaches either. Code-first frameworks, coming to your IDE soon This article was fairly theoretical and did not contain much code – we still hope we could spark your interest in code-first development. To see further practical examples and learn more about the code-first development experience, stay tuned and keep an eye on the Prisma Twitter account over the next few days 👀 What do you think of this article? Join the Prisma Slack to discusst SDL-first and code-first development with fellow GraphQL enthusiasts. 🙏 A huge thank you to Sashko and the Apollo team for their feedback on the article! Source: The Problems of “Schema-First” GraphQL Server Development | Prisma

    Read at 10:18 pm, Dec 9th

  • Amazon Grows in New York, Reviving Debate Over Abandoned Queens Project - The New York Times

    Representative Alexandria Ocasio-Cortez and other critics of an earlier proposal said a move to add offices in Manhattan proved them right. An Amazon warehouse on Staten Island. The company has more than 8,000 employees in New York City. Credit...Hiroko Masuike/The New York Times Published Dec. 6, 2019Updated Dec. 9, 2019, 10:01 a.m. ET Amazon said on Friday that it would lease office space in Midtown Manhattan for more than 1,500 employees, increasing its presence in New York City less than a year after abandoning plans for a second headquarters in Queens in the face of stiff local opposition. The retail giant said it had a signed a lease for 350,000 square feet in a 10th Avenue building near the Hudson Yards development. The offices will be occupied by workers in Amazon’s consumer and advertising units, the company said. The Manhattan lease does not qualify for the kind of tax credits and other government sweeteners the company had won in exchange for building a huge campus in Long Island City that was to employ more than 25,000 people. The incentives for the Queens project totaled $3 billion, touching off a contentious debate about the value of using outsize public subsidies to woo wealthy companies — and about whether such bait was necessary in a talent-rich city like New York. Word that the company was adding office space in Manhattan to its existing operations elsewhere in Midtown, which was first reported by The Wall Street Journal, led leading critics of the Long Island City venture to take what amounted to a second victory lap. “Won’t you look at that,” Representative Alexandria Ocasio-Cortez, who represents the area where the campus was to be built, wrote on Twitter. “Amazon is coming to NYC anyway - *without* requiring the public to finance shady deals, helipad handouts for Jeff Bezos, & corporate giveaways.” State Senator Michael Gianaris, a Queens Democrat who initially supported the project but changed his mind after learning the details of the incentive package, said in a statement, “Amazon is coming to New York, just as they always planned.” “Fortunately,” he added, “we dodged a $3 billion bullet by not agreeing to their subsidy shakedown earlier this year.” Others were quick to argue that the Manhattan office space and the 1,500 employees it will house pale next to the vast campus proposed for Queens and the 25,000 people that Amazon pledged to employ there. “This is a tiny fraction of the jobs, with no help for public housing residents or locals, in a place that was going to be developed and have jobs anyway,” Eric Phillips, a former press secretary for Mayor Bill de Blasio, wrote on Twitter. In an interview, Mr. Gianaris discounted that argument. He predicted that Amazon would continue to expand in New York steadily to the point that the size of its local force would ultimately equal what had been promised in Queens. “This is where the talent is,” Mr. Gianaris said, noting that both Google and Facebook had announced substantial expansions in Manhattan in the past year. “They can’t sacrifice the talent to the competition.” Amazon’s growth in New York has been healthy in recent years. In 2017 — as it searched for where to put a second headquarters to augment its Seattle base — Amazon said separately that it planned to bring more than 2,000 jobs to New York City over three years and to create about 6,000 jobs in New York State by 2019. When it dropped the Queens project in February, the company said it had more than 5,000 employees in Brooklyn, Manhattan and Staten Island, where it operates a warehouse, and that it planned “to continue growing these teams.” On Friday, it put the size of its New York City work force at over 8,000, with 3,500 of those employed at what it calls its New York City tech hub. It was unclear whether the 1,500 people expected to work in the 10th Avenue building starting in late 2021 would fill newly created positions. “We plan to continue to hire and grow organically across our 18 tech hubs, including New York City,” an Amazon spokeswoman said. The company’s decision to leave Queens behind came several months after it ended its much-publicized second-headquarters search by splitting what had been envisioned as a single huge, 50,000-employee campus between Long Island City and Arlington, Va. The proposal had supporters, including Mr. de Blasio and Gov. Andrew M. Cuomo, but the opposition rallied by Ms. Ocasio-Cortez, Mr. Gianaris, progressive activists, union leaders and others made Amazon, which has encountered resistance in its hometown, wary of pressing the issue. Source: Amazon Grows in New York, Reviving Debate Over Abandoned Queens Project – The New York Times

    Read at 06:41 pm, Dec 9th

  • That impeachment hearing protester was actually an InfoWars reporter and Pizzagate conspiracy theorist

    It took a few weeks, but the impeachment hearings finally saw their first protester. House Judiciary Committee Chair Jarrold Nadler (D-N.Y.

    Read at 05:22 pm, Dec 9th

  • Pete Buttigieg Called Me. Here's What Happened

    The first thing you should know about me is that I absolutely hate talking on the phone. My friends, family and co-workers all know this about me. It’s not the talking that bothers me, it’s the anticipation angst from waiting for a phone call.

    Read at 05:17 pm, Dec 9th

  • TypeScript 3.7 Utility Types | Printable PDF Cheat Sheet | Else Web Development

    .entry-header Learning modern TypeScript is not easy, especially when the Language Specification was last updated in Jan 2016. This is eventually going to be remedied with a brand new version of the handbook, but the pace it is being written is glacial. Much of the current official documentation and general blog based information is outdated too. To add to this horror, well-meaning people seem to have confused the meaning of the words ‘cheat sheet’ with ‘pages of vaguely related information in an unprintable format’. Maybe younger developers have never encountered a ‘printer’ device before? A decrepit antique that feeds on the corpses of dead trees and splits out thin slices of white ‘analogue information’ that requires physical space to store. I am of the opinion that a nicely formatted and printed cheat sheet is a fantastic aid to learning, so here is one I made for all the TypeScript 3.7 utility types. I took the official handbook .md file and brought it up to date by adding the Paramaters<T> and ConstructorParamters<T> types using examples from the awesome Marius Schulz Blog. I then added page breaks with <div style="page-break-after: always;"></div>, and rendered it using PanDoc > HTML > Chromium PDF export. Hope you like it! ** Update, myself and another contributor sent in pull requests that were accepted. The official utility types page of the documentation has now been updated… but you still want this PDF for nicely formatted printing. Partial<T> Constructs a type with all properties of T set to optional. This utility will return a type that represents all subsets of a given type. Example interface Todo { title: string; description: string; } function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) { return { ...todo, ...fieldsToUpdate }; } const todo1 = { title: "organize desk", description: "clear clutter" }; const todo2 = updateTodo(todo1, { description: "throw out trash" }); Readonly<T> Constructs a type with all properties of T set to readonly, meaning the properties of the constructed type cannot be reassigned. Example interface Todo { title: string; } const todo: Readonly<Todo> = { title: "Delete inactive users" }; todo.title = "Hello"; This utility is useful for representing assignment expressions that will fail at runtime (i.e. when attempting to reassign properties of a frozen object). function freeze<T>(obj: T): Readonly<T>; Record<K,T> Constructs a type with a set of properties K of type T. This utility can be used to map the properties of a type to another type. Example interface PageInfo { title: string; } type Page = "home" | "about" | "contact"; const x: Record<Page, PageInfo> = { about: { title: "about" }, contact: { title: "contact" }, home: { title: "home" } }; Pick<T,K> Constructs a type by picking the set of properties K from T. Example interface Todo { title: string; description: string; completed: boolean; } type TodoPreview = Pick<Todo, "title" | "completed">; const todo: TodoPreview = { title: "Clean room", completed: false }; Omit<T,K> Constructs a type by picking all properties from T and then removing K. Example interface Todo { title: string; description: string; completed: boolean; } type TodoPreview = Omit<Todo, "description">; const todo: TodoPreview = { title: "Clean room", completed: false }; Exclude<T,U> Constructs a type by excluding from T all properties that are assignable to U. Example type T0 = Exclude<"a" | "b" | "c", "a">; type T1 = Exclude<"a" | "b" | "c", "a" | "b">; type T2 = Exclude<string | number | (() => void), Function>; Constructs a type by extracting from T all properties that are assignable to U. Example type T0 = Extract<"a" | "b" | "c", "a" | "f">; type T1 = Extract<string | number | (() => void), Function>; NonNullable<T> Constructs a type by excluding null and undefined from T. Example type T0 = NonNullable<string | number | undefined>; type T1 = NonNullable<string[] | null | undefined>; ReturnType<T> Constructs a type consisting of the return type of function T. Example type T0 = ReturnType<() => string>; type T1 = ReturnType<(s: string) => void>; type T2 = ReturnType<<T>() => T>; type T3 = ReturnType<<T extends U, U extends number[]>() => T>; type T4 = ReturnType<typeof f1>; type T5 = ReturnType<any>; type T6 = ReturnType<never>; type T7 = ReturnType<string>; type T8 = ReturnType<Function>; InstanceType<T> Constructs a type consisting of the instance type of a constructor function type T. Example class C { x = 0; y = 0; } type T0 = InstanceType<typeof C>; type T1 = InstanceType<any>; type T2 = InstanceType<never>; type T3 = InstanceType<string>; type T4 = InstanceType<Function>; Required<T> Constructs a type consisting of all properties of T set to required. Example interface Props { a?: number; b?: string; } const obj: Props = { a: 5 }; const obj2: Required<Props> = { a: 5 }; ThisType<T> This utility does not return a transformed type. Instead, it serves as a marker for a contextual this type. Note that the --noImplicitThis flag must be enabled to use this utility. Example type ObjectDescriptor<D, M> = { data?: D; methods?: M & ThisType<D & M>; }; function makeObject<D, M>(desc: ObjectDescriptor<D, M>): D & M { let data: object = desc.data || {}; let methods: object = desc.methods || {}; return { ...data, ...methods } as D & M; } let obj = makeObject({ data: { x: 0, y: 0 }, methods: { moveBy(dx: number, dy: number) { this.x += dx; this.y += dy; } } }); obj.x = 10; obj.y = 20; obj.moveBy(5, 5); In the example above, the methods object in the argument to makeObject has a contextual type that includes ThisType<D & M> and therefore the type of this in methods within the methods object is { x: number, y: number } & { moveBy(dx: number, dy: number): number }. Notice how the type of the methods property simultaneously is an inference target and a source for the this type in methods. The ThisType<T> marker interface is simply an empty interface declared in lib.d.ts. Beyond being recognized in the contextual type of an object literal, the interface acts like any empty interface. Parameters<T> The Parameters<T> type lets us extract all parameter types of a function type. It produces a tuple type with all the parameter types (or the type never if T is not a function). Example type A = Parameters<() => void>; type B = Parameters<typeof Array.isArray>; type C = Parameters<typeof parseInt>; type D = Parameters<typeof Math.max>; The Array.isArray() method expects exactly one argument of an arbitrary type; this is why type B is resolved as [any], a tuple with exactly one element. The Math.max() method, on the other hand, expects arbitrarily many numeric arguments (not a single array argument); therefore, type D is resolved as number[] (and not [number[]]). ConstructorParameters<T> The ConstructorParameters<T> type lets us extract all parameter types of a constructor function type. It produces a tuple type with all the parameter types (or the type never if T is not a function). Example type A = ConstructorParameters<ErrorConstructor>; type B = ConstructorParameters<FunctionConstructor>; type C = ConstructorParameters<RegExpConstructor>; .entry-content .clear Source: TypeScript 3.7 Utility Types | Printable PDF Cheat Sheet | Else Web Development

    Read at 03:57 pm, Dec 9th

  • Achieving concurrency in Go - RunGo - Medium

    Why have I been blocked? This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data. Source: Achieving concurrency in Go – RunGo – Medium

    Read at 03:53 pm, Dec 9th

  • Corbyn reveals secret documents that 'confirm Tory plot to sell off NHS in US trade talks with Trump'

    Jeremy Corbyn has released uncensored official documents which he says provides confirmation that the NHS is on the table in trade talks with the USA.

    Read at 03:01 pm, Dec 9th

  • Warren and Biden lose ground, Sanders moves ahead in California’s shifting 2020 Democratic race

    By Staff Writer WASHINGTON — The Democratic presidential contest in California remains extremely fluid — but not enough, at least so far, to provide an opening for Michael Bloomberg, who entered the race two weeks ago and was banking on winning big in the delegate-rich state, a new poll for the

    Read at 02:58 pm, Dec 9th

  • Tech companies monitor schoolkids across America. These parents are making them delete the data

    Parents at a public school district in Maryland have won a major victory for student privacy: tech companies that work with the school district now have to purge the data they have collected on students once a year.

    Read at 02:54 pm, Dec 9th

  • The Social Justice Sector Has an Internal Racism Problem

    Nine months into a nonprofit job that I loved — where I was the first woman of color in an executive role — I was forced to leave due to discrimination, exploitation, and retaliation from the young, liberal, white, woman executive director.

    Read at 02:49 pm, Dec 9th

  • Building animated draggable interfaces with Vue.js and Tailwind

    The frontend landscape changed quite a lot in the last years (hopefully for the better). Now there are tools and technologies that help us achieve great results pretty quickly and efficiently. Among those tools the combination of Vue.

    Read at 02:45 pm, Dec 9th

  • ‘Bleak’ U.N. Report on a Planet in Peril Looms Over New Climate Talks

    With world leaders gathering in Madrid next week for their annual bargaining session over how to avert a climate catastrophe, the latest assessment issued by the United Nations said Tuesday that greenhouse gas emissions are still rising dangerously.

    Read at 02:38 pm, Dec 9th

  • In bleak report, U.N. says drastic action is only way to avoid worst effects of climate change

    The world has squandered so much time mustering the action necessary to combat climate change that rapid, unprecedented cuts in greenhouse gas emissions offer the only hope of averting an ever-intensifying cascade of consequences, according to new findings from the United Nations.

    Read at 02:35 pm, Dec 9th

  • Progressives Are Suddenly Really Mad at Elizabeth Warren

    Big, structural change? More like big, structural incrementalism. That’s what some progressives are saying about Sen. Elizabeth Warren (D-Mass.

    Read at 02:29 pm, Dec 9th

  • Donald McGahn Must Testify to Congress, Judge Rules; Administration Will Appeal

    A judge rejected the Trump administration’s argument that senior White House officials were immune from congressional subpoenas. WASHINGTON — The former White House counsel Donald F.

    Read at 02:27 pm, Dec 9th

  • ‘Broadband communism’? Outside the UK, public broadband is a raving success

    However, in reality, governments around the world are taking the lead on developing the digital infrastructure necessary to develop thriving 21st century economies (just as they did with the electricity networks, roads, bridges, railroads, airports, and other vital economic infrastructure of the 20t

    Read at 01:36 pm, Dec 9th

  • Re-Licensing Sentry | Product Blog • Sentry

    Sentry provides error tracking that shows you every crash in your stack as it happens, with the details needed to prioritize, identify, reproduce, and fix each issue. It also allows your users to send feedback that helps your support team respond appropriately. Each month we process billions of exceptions from the most popular products on the internet. Source: Re-Licensing Sentry | Product Blog • Sentry

    Read at 01:24 pm, Dec 9th

  • The people behind JavaScript: Allen Wirfs-Brock

    👉 Make sure to follow Allen on Twitter Who are you and what do you do? I'm a software architect and developer specializing in dynamic programming languages. In the 1980s and 90s I was deeply involved in trying to make Smalltalk an industrial strength programming language. It almost worked. I've been recognized as an ACM Distinguished Engineer and an Ecma International Fellow. I was the editor for the ES5, ES5.1, ES2015. How did you get into programming? I became intrigued with them in 6th grade, when small computers filled large rooms. What do you like about JavaScript? Its ubiquity. JavaScript is the language of the web and is likely to outlive us all. How did you get involved in the development of ECMAScript? In early 2007, I was working as a software architect at Microsoft. At the time, nobody at MSFT cared very much about JavaScript. I saw a need and opportunity to improve JavaScript/ECMAScript for the long term and positioned myself to lead Microsoft's reengagement with TC39. What contribution are you most proud of? Producing the ECMAScript 2015 Language Specification and contributing to the design of the language it defines. Part of my role as editor was making sure that all the good ideas actually fit together coherently. Which upcoming proposal are you most excited about, and why? The Realms API and closely-related Secure ECMAScript proposals. These are foundational proposals that enable building secure sandboxing of untested JavaScript code within JavaScript applications. What is the most fun about being a part of the development of ECMAScript? Impact – knowing that you are having a direct impact of the world's most widely used programming language. You are touching people everywhere. What is the hardest part about developing a programming language? Throwing out all the good ideas that that would make the language too complex – then trying to make sure that the features you keep play nicely with each other. Do you think JS is a complex language now? Think what it would be like if hundreds of additional good feature ideas where incorporated into it. What do you wish you knew before you started contributing to the development of ECMAScript? The full history of the language and its standardization efforts. What was the reasoning behind past decisions. That's why I've spent most of the last two years working on an in depth technical history of the evolution of JavaScript/ECMAScript from 1995 through 2015. It will be completed and available around the middle of 2020. How do you hope JavaScript will evolve in the future? I hope that TC39 fills in a few key fundamental holes (for example, Realms) and slows down accretion of faddish surface features. JavaScript is unlikely to ever be the world's best programming language but its role on the web means that it is likely to be one of the world's longest-lived programming languages. We need to make sure that in 2119 somebody who wants to get a glimpse of what software development was like in the past can open the "2019 JavaScript Advent Calendar" and it will just work! Source: The people behind JavaScript: Allen Wirfs-Brock

    Read at 01:17 pm, Dec 9th

  • Zero BS CRM 3.0 Improves UI, Changes Database Structure, and Becomes More Extendable – WordPress Tavern

    The team behind Zero BS CRM launched version 3.0 of their WordPress plugin today. This is the first major release since the plugin was acquired by Automattic in August. The updated plugin uses custom database tables, opens the plugin for more extensions, and has a more consistent UI than previous versions. CRM is an acronym for “customer relationship management.” CRM systems allow businesses to manage their customer relationships through an interface. How CRM systems work can vary greatly, depending on the software used. In general, the goal is to help manage contacts, sales, and productivity. Zero BS CRM was co-created by Mike Stott and Woody Hayday. Despite a low number of plugin users (around 1,000 at acquisition), Automattic acquired the plugin based on the strength of the product. Currently, Stott and Hayday are the primary developers on the plugin and maintain more than 30 commercial extensions for it. Many CRM solutions are SaaS products, such as Salesforce CRM and HubSpot CRM. “The main benefit of ZBS CRM over online SaaS type solutions is it sits in your WP admin dashboard, and you own your own data,” said Stott. Version 3.0 of the plugin improves in several key areas. One major change is the switch to custom database tables rather than pigeon-holing everything into a custom post type. This change should speed up accessing data such as contacts and transactions in large databases. Users should benefit from a much improved and consistent UI from previous versions. Zero BS CRM does not strictly follow the core WordPress admin UI. “When looking at ZBS CRM and how to tie in all our menu items into the WordPress UI – it wasn’t easy,” said Stott. “We settled on using a UI framework with our own top menu, and a natural follow-on for that was to draw our list views using that same UI and button systems. Whether we move this back or not depends on feedback from our users — we get a lot of positive feedback on how easy it is to navigate around and wouldn’t want to change something that’s been getting good feedback.” Contact management screen in the Zero BS CRM plugin. Moving to custom tables over custom post types has also helped improve elements of the UI. Stott said a huge advantage is not having third-party plugins accidentally adding themselves to the plugin’s admin pages, such as having unnecessary SEO options on contact records. Another big change in 3.0 was building out a more extendable foundation for the plugin. This will open up custom CRM objects in the future. For example, plugin users could manage resources such as “properties” or “campuses” along with customer contact data. This update creates more potential for industry-specific extensions. “It really opens the door for more extendibility in the future,” said Stott, “and through an improved API in 2020 will allow for us to do more work across platforms and open up our CRM tools to more people.” The Zero BS CRM plugin remains free and is available in the WordPress plugin repository. The primary source of income comes from its extension bundles, which are priced monthly and billed yearly. The website currently offers freelancer ($11/month), entrepreneur ($17/month), and elite ($30/month) pricing options. It also has a reseller plan available. The Move to Automattic When the plugin was first acquired, there was an initial idea to rebrand as “Jetpack CRM.” However, they have maintained the Zero BS CRM branding with an acronym instead of the direct expletive for “BS.” A rebrand may still be on the table in 2020 or beyond. “We’ve been gathering user feedback and sentiment following the minor changes to ZBS CRM and the initial reactions if we were to rename as Jetpack CRM,” said Stott. “Since the shorter name, there’s been less objection or negative feelings, which puts less pressure on a big rebrand project, but it’s certainly something we’ll be coming back to.” Stott said the primary focus since the acquisition has been less on branding and more on delivering 3.0 to the existing customer base. The acquisition by Automattic has helped with how their two-person team works. “The main thing is being able to lean on the amazing team and people throughout Automattic,” said Stott. “In the past, we’d only have Woody and my input, now we can reach out to experts in design, marketing, plus much more, and bounce our ideas around a vast pool of experience.” He explained that the additional support resources of Automattic’s Happiness Engineers means that he and his partner can focus more on engineering and growing the product and team. The acquisition of Zero BS CRM came during a busy year for Automattic. With major moves such as acquiring Tumblr and the Salesforce investment, this small plugin has mostly flown under the radar in comparison. Stott and Hayday have big plans for 2020. They would like to grow the engineering team and explore bringing their tools to more WordPress.com users. The plugin’s growth has remained stable since the acquisition, according to Stott. “The announcement brought us some additional customers who saw the backing from Automattic as strong advocacy for the plugin over other solutions in the WordPress space, so they made the decision to join us,” he said. The plugin has doubled its active install count and now serves over 2,000 users. The team expects to continue growing in the coming months. Like this: Like Loading... Source: Zero BS CRM 3.0 Improves UI, Changes Database Structure, and Becomes More Extendable – WordPress Tavern

    Read at 01:04 pm, Dec 9th

  • Zero BS CRM 3.0 Improves UI, Changes Database Structure, and Becomes More Extendable – WordPress Tavern

    The team behind Zero BS CRM launched version 3.0 of their WordPress plugin today. This is the first major release since the plugin was acquired by Automattic in August. The updated plugin uses custom database tables, opens the plugin for more extensions, and has a more consistent UI than previous versions. CRM is an acronym for “customer relationship management.” CRM systems allow businesses to manage their customer relationships through an interface. How CRM systems work can vary greatly, depending on the software used. In general, the goal is to help manage contacts, sales, and productivity. Zero BS CRM was co-created by Mike Stott and Woody Hayday. Despite a low number of plugin users (around 1,000 at acquisition), Automattic acquired the plugin based on the strength of the product. Currently, Stott and Hayday are the primary developers on the plugin and maintain more than 30 commercial extensions for it. Many CRM solutions are SaaS products, such as Salesforce CRM and HubSpot CRM. “The main benefit of ZBS CRM over online SaaS type solutions is it sits in your WP admin dashboard, and you own your own data,” said Stott. Version 3.0 of the plugin improves in several key areas. One major change is the switch to custom database tables rather than pigeon-holing everything into a custom post type. This change should speed up accessing data such as contacts and transactions in large databases. Users should benefit from a much improved and consistent UI from previous versions. Zero BS CRM does not strictly follow the core WordPress admin UI. “When looking at ZBS CRM and how to tie in all our menu items into the WordPress UI – it wasn’t easy,” said Stott. “We settled on using a UI framework with our own top menu, and a natural follow-on for that was to draw our list views using that same UI and button systems. Whether we move this back or not depends on feedback from our users — we get a lot of positive feedback on how easy it is to navigate around and wouldn’t want to change something that’s been getting good feedback.” Contact management screen in the Zero BS CRM plugin.Moving to custom tables over custom post types has also helped improve elements of the UI. Stott said a huge advantage is not having third-party plugins accidentally adding themselves to the plugin’s admin pages, such as having unnecessary SEO options on contact records. Another big change in 3.0 was building out a more extendable foundation for the plugin. This will open up custom CRM objects in the future. For example, plugin users could manage resources such as “properties” or “campuses” along with customer contact data. This update creates more potential for industry-specific extensions. “It really opens the door for more extendibility in the future,” said Stott, “and through an improved API in 2020 will allow for us to do more work across platforms and open up our CRM tools to more people.” The Zero BS CRM plugin remains free and is available in the WordPress plugin repository. The primary source of income comes from its extension bundles, which are priced monthly and billed yearly. The website currently offers freelancer ($11/month), entrepreneur ($17/month), and elite ($30/month) pricing options. It also has a reseller plan available. The Move to Automattic When the plugin was first acquired, there was an initial idea to rebrand as “Jetpack CRM.” However, they have maintained the Zero BS CRM branding with an acronym instead of the direct expletive for “BS.” A rebrand may still be on the table in 2020 or beyond. “We’ve been gathering user feedback and sentiment following the minor changes to ZBS CRM and the initial reactions if we were to rename as Jetpack CRM,” said Stott. “Since the shorter name, there’s been less objection or negative feelings, which puts less pressure on a big rebrand project, but it’s certainly something we’ll be coming back to.” Stott said the primary focus since the acquisition has been less on branding and more on delivering 3.0 to the existing customer base. The acquisition by Automattic has helped with how their two-person team works. “The main thing is being able to lean on the amazing team and people throughout Automattic,” said Stott. “In the past, we’d only have Woody and my input, now we can reach out to experts in design, marketing, plus much more, and bounce our ideas around a vast pool of experience.” He explained that the additional support resources of Automattic’s Happiness Engineers means that he and his partner can focus more on engineering and growing the product and team. The acquisition of Zero BS CRM came during a busy year for Automattic. With major moves such as acquiring Tumblr and the Salesforce investment, this small plugin has mostly flown under the radar in comparison. Stott and Hayday have big plans for 2020. They would like to grow the engineering team and explore bringing their tools to more WordPress.com users. The plugin’s growth has remained stable since the acquisition, according to Stott. “The announcement brought us some additional customers who saw the backing from Automattic as strong advocacy for the plugin over other solutions in the WordPress space, so they made the decision to join us,” he said. The plugin has doubled its active install count and now serves over 2,000 users. The team expects to continue growing in the coming months. Like this:Like Loading... Source: Zero BS CRM 3.0 Improves UI, Changes Database Structure, and Becomes More Extendable – WordPress Tavern

    Read at 01:04 pm, Dec 9th

  • Boom. We just dinosized your movie collection – for free. | Plex

    Wow. Today is the day we’ll start streaming thousands of free movies, TV shows, extreme sports films, music documentaries, Bollywood musicals, and more. Some super familiar stuff (Hey there, Nic Cage! Looking good, Tom Cruise! You’re totally Overboard, Goldie Hawn!) and super obscure stuff too (welcome to Plex, Squid Man!). All of this goodness is ready to go as soon as you open Plex. While there might be, oh, one or two other streaming services already out there 😉, we’re building on our decade of extreme passion for media to deliver the best experience possible, while also giving you the control and customization to stream it your way. So dip your toes in and give it a whirl! As with all the Plex content offerings, you can move the free movie source up and down your sidebar or even hide it forever—you’re always in control of your own destiny, or at least your own interface. Over time, we’ll be adding more stuff from different studios and creators—from Oscar-winning Hollywood movies to the latest from India, Russia, China, Japan, Africa, Latin America, Australia, New Zealand, and Europe to really cool independent movies fresh off the festival circuit. For those who are into acronyms—looking at all you SCUBA heads and NASA geeks—this type of offering is known as Ad-supported Video On Demand, or AVOD. Our hope is that Plex becomes your favorite source for free shows and movies, which will all be available across the vast expanse of Plex-enabled devices. And all, you know, for free. Okay. So how exactly does this new free service work? 1. If you already have content inside Plex: Congrats! Your mediaverse just got a little bit bigger. New free movies and series content will be available in your navigation and homescreen just like all of your other media in Plex, which you can customize or turn off. We’ll also be able to recommend content based on your media collection, just like we do with your music library and TIDAL. You decide whether you want to watch any of the recommended free titles. 2. If you don’t have content inside Plex: It’s now easier than ever to experience the highest-rated media app around. Enjoy our best-in-class interface for streaming the movies, TV shows, podcasts, documentaries, and music you love. No hard drive or personal media collection necessary. We’ll bring all the good stuff directly to you. So, about those little ad-breaks in the free movies and TV shows Our goal is to bring this great content from big studios and independent producers from around the globe to you for free. In exchange, we’re asking for a bit of your time to watch some ads. We think it’s a fair deal, but of course, you’ll be the judge. Besides—you gotta go to the bathroom sometime, right? Wait, are you going to be putting ads in my personal content? Absolutely not! That would be a really terrible idea for many, many reasons. Your media collection—including your recorded movies and TV shows, home videos, photos, music collection, and more—will continue to stream to all of your devices ad-free. Unless, of course, you just happen to collect TV commercials in your personal media collection 😉. Boldly streaming where no other company has streamed before While there are certainly other free streaming services out there, we’re the first to offer a vast, free, diverse collection of content for a truly global audience. Starting today, Plex will deliver more content to more countries than any other free streaming service to date. We wanted to offer more entertainment—both classics and new favorites—and do so in a way that is high-quality (for those who care about encoding quality) while serving only about one-third the amount of ads you’d expect on cable television. Basically, we wanted to build a free streaming service that we would want to watch ourselves. And of course, Plex isn’t only a free streaming service. We provide you and your family a single, beautiful place to curate and stream all your stored videos and photos, favorite podcasts, movies, web shows, news, live TV, and even your carefully curated music collection. In other words, with Plex you become master of your mediaverse. At Plex, we stream it your way So give it a spin. Prioritize the types of content and the sources you want to see, or even re-organize your app’s interface to truly make it your own. Discover our dozens of new free collections like “ Anime movies that make Sumo wrestlers cry.” Or re-discover those guilty pleasures in “Movies you hate to love.” If you’ve got the emotional intelligence for it, why not try our “Feel like some feels” collection. Or dive deep into the Kung Fu movies and 80s-action classics with our “Fight Night” collection. Besides, who doesn’t want to watch Michael J. Fox surf on top of a van dressed up like a werewolf for free? More goodness to come And rest assured, we’re working on improving this new source all the time. Some upgrades to keep an eye out for in the short term include improved subtitle support around the globe, additional discovery and browse features, and an enhanced watch list to keep track of everything you want to watch! Learn more about accessing the new, free content as well as answers to other common questions on our support site. Source: Boom. We just dinosized your movie collection – for free. | Plex

    Read at 12:52 pm, Dec 9th

  • The Aesthetic-Accessibility Paradox

    Every interface has a subset of users that make up the majority and minority. The majority of users usually have normal vision, while the minority have some form of visual impairment. There’s a big difference between what normal-visioned users see versus what color blind and low vision users see.

    Read at 12:43 pm, Dec 9th

  • The Fight Continues: NYC-DSA and Struggle for Housing Justice

    Last year, NYC-DSA took on the fight for universal rent control as a citywide priority in the 2018-2019 legislative session.

    Read at 01:56 am, Dec 9th

Day of Dec 8th, 2019

  • Gutenberg: One Year Later – WordPress Tavern

    As we quickly head into the final weeks of 2019, we also pass the first anniversary of WordPress 5.0 and, subsequently, Gutenberg coming headlong into our lives. Love it or hate it, Gutenberg is here to stay. If you had asked my thoughts on it last December, I would have probably sided with a large portion of other WordPress users. What are you doing? WordPress is fine, leave it alone! Stop forcing me to use this! Here we are, twelve months later, and you know what? I LOVE IT. And, I am not alone. When it comes to writing content, I cannot imagine using the Classic Editor anymore. Sure, for a few paragraphs, the Classic Editor is fine. However, when you need to make a 4,000+ word post, Gutenberg and the new block system make things a lot easier. Yes, the UI is a struggle for someone brand new to WordPress. We have all heard the “Wait, I thought you said this was like Word?” line. A good onboarding process would tackle that going forward. For the rest of us, if you have not adopted Gutenberg yet, you should take another look at it. The Need for a New Editor Let’s be honest. The Classic Editor was great for short posts, a couple of headlines and paragraphs, job done. But, how often were you going into the Text tab to remove an extra line break, fix a shortcode, or cut and paste a section to somewhere else in the post?  At best, it was a struggle. Often, it was excruciating to get your post just right before publishing. Not only will I not miss this, but I am pleased that new users will not be exposed to it anymore either. Classic Editor – Text tab in action When I first heard of Gutenberg — before it was released in WordPress 5.0 — I installed the plugin and was immediately confused and slightly bewildered at the options. I wondered how I would edit in the future. I, among many others, probably gave out the same noises as when Facebook and Twitter reveal a huge overhaul of their UI, agreeing with everyone that things would never be the same again. This was a mistake. Of course, I was both right and wrong at the same time. I just didn’t know it. Editing would not be the same again. Instead, it would be a lot better (with some adjustment). I also know that many people will not agree with me and do not like the way Gutenberg looks or behaves to this day. But, if you give it some time and understand how it can make your life easier, it will do just that. First, take the time to work out the difference between Blocks and Document. On the left you have all the blocks for your post or page, inserting them in merrily as you go. On the right, the Document panel controls everything else, handily changing when you need to fine-tune a block. Gutenberg block editor in action One of the most common complaints I have read is people struggling with the toolbar that appears as you hover over each block. There is a simple solution to this, and when it is enabled, the majority of people suddenly start to love it! Make sure you set the view to “Top Toolbar” in the Gutenberg options. Now you have a distraction and clutter-free editing environment to work with. Gutenberg vs. Page Builders Gutenberg is not a page builder, and it is a common argument thrown out by people on why they refuse to use it. They are right, it is not a replacement for the likes of Elementor or Beaver Builder. If you remove the comparison to page builders from your mind, you will find adapting to it is much easier. My peers and I regularly chat about Gutenberg and agree it is already great for writing. The post creation process is a breath of fresh air. Others have great stories from their clients about being able to produce content and edit it with ease, and the number of editor-related support requests is down, which can only be a good thing. However, many of us would not use it for designing pages. Instead, we still prefer to use one of the many page builders for that complete control. Gutenberg Phase 2 will allow editing of the site to areas outside of the main content (e.g., headers, footers, sidebars) and will creep further into the page builder category, which means we will have a strange blend of Gutenberg and page builders living side by side on many sites soon. Will it remove the complete need for themes? Who knows? I suspect we will have people further divided into opposing camps going forward, but what a great opportunity for us to collectively work on for a better overall experience in the end. By the Numbers Let us take a quick look at Gutenberg and its penetration to date. Currently, 63.8% of all WordPress installs are running 5.x onward according to WordPress.org, which means Gutenberg is available natively on nearly two-thirds of all WordPress installs. But, it is not all red roses when it comes to adoption. The Classic Editor plugin has over 5 million active installs (and a rather biased 723 five-star reviews, such as “Keep this forever” and “Never going to give it up!”). It is also currently in the top five of the most popular plugins. Is this the backlash against Gutenberg or incompatibility with older themes forcing users to use the Classic Editor for now? At a guess, a good majority is probably the latter combined with some diehards. But, look at the graph below from the Classic Editor plugin page. Growth is declining. That is not a movement of people who continue to install Classic Editor on new installs and refuse to adapt. Classic Editor adoption will likely continue falling, and perhaps the original date of it being supported until 2022 isn’t that far-fetched after all (note: they have said they will continue to support it longer if needed). On the flip-side, the Gutenberg plugin has 200,000 active installs and a whopping two-thirds of reviews (2,003) are a paltry one star. However, many are merely unhelpful complaints (e.g., “This is junk” and “Destroy it”). They do not tell the true story to novices. As you can see from the graph below for the Gutenberg plugin, active install growth is up and continues to climb. It is not at the same pace as the decline with the Classic Editor, but that is probably because it is bundled with WordPress now. One thing people seem to forget is Gutenberg is a plugin in and of itself. It is updated frequently, whereas the majority of users only see changes to it when there is a WordPress core update. If you can see past the fields of one-star reviews and install the plugin, you will be rewarded with more frequent updates to the experience. For example, version 7.0 recently added in the Navigation block as stable, allowing users to quickly create a menu of links. Don’t get me wrong; this does require theme integration for it to work, but you can get a better idea of where it is heading on a more frequent basis this way (7.0 is expected to ship with WordPress 5.4 in March/April 2020). Block Party Compatibility with Gutenberg continues at a quick pace. With over 21 pages of block-enabled plugins available on WordPress.org, pretty much all the popular plugins have solutions in place. A fair amount of plugin updates these days are also adding new and enhanced blocks as standard. If those are not enough for you, we also now have a new breed of block-specific plugins. There is a growing trend of plugins devoted to purely enhancing the style and number of blocks you can add to your site. Popular Gutenberg-focused plugins such as Stackable and EditorsKit add further styling and editing abilities, bringing you another step closer to full-page design and enhancing your content. EditorsKit – a purely Gutenberg plugin. Because no one knows how far Gutenberg will go and which toes it will step on, block plugins may have a fight on their hands in the future. At the pace they are being released and updated, it is a good sign of a committed global collective who not only believe in the future of blocks but is excited about it too. What Does the Future Hold? Gutenberg is here to stay, and I don’t think any of us have ever denied that. It is probably not an issue for anyone who started using WordPress for the first time this year. Thankfully, for those already deeply embedded in WordPress, things are getting easier (and I would say more enjoyable) with the growth of the new Gutenberg-specific plugins. With the advent of platforms such as Wix and Squarespace, it was obvious that WordPress needed something to make it more user-friendly and Gutenberg is a solid attempt at that. It is still a bit rough around the edges, but the days we look back nostalgically at the Classic Editor are likely numbered. How will it look at the end of 2020? Will you still be using the Classic Editor? Like this: Like Loading... Source: Gutenberg: One Year Later – WordPress Tavern

    Read at 05:33 pm, Dec 8th

Day of Dec 7th, 2019

  • Broadcast Journalist Makes History with Face Tattoos

    If you were to close your eyes and imagine the appearance of a television journalist, you'd likely conjure up a clean cut individual without a shred of visible ink on their bodies.

    Read at 10:42 pm, Dec 7th

  • Engineering Blog

    Apologies to the folks who found this post while searching for “automated WebGL testing,” “how to write cross-browser WebGL tests,” or similar. I’ve been there, and it is not my favorite part of the job.

    Read at 06:26 pm, Dec 7th

Day of Dec 6th, 2019

  • How Artists on Twitter Tricked Spammy T-Shirt Stores Into Admitting Their Automated Art Theft – Waxy.org

    Yesterday, an artist on Twitter named Nana ran an experiment to test a theory. Their suspicion was that bots were actively looking on Twitter for phrases like “I want this on a shirt” or “This needs to be a t-shirt,” automatically scraping the quoted images, and instantly selling them without permission as print-on-demand t-shirts. Dozens of Nana’s followers replied, and a few hours later, a Twitter bot replied with a link to the newly-created t-shirt listing on Moteefe, a print-on-demand t-shirt service. Several other t-shirt listings followed shortly after, with listings on questionable sites like Toucan Style, CopThis, and many more. Spinning up a print-on-demand stores is dead simple with platforms like GearBubble, Printly, Printful, GearLaunch (who power Toucan Style), and many more — creating a storefront with thousands of theoretical product listings, but with merchandise only manufactured on demand through third-party printers who handles shipping and fulfillment with no inventory. Many of them integrate with other providers, allowing these non-existent products to immediately appear on eBay, Amazon, Etsy, and other stores, but only manufactured when someone actually buys them. The ease of listing products without manufacturing them is how we end up with bizarre algorithmic t-shirts and entire stock photo libraries on phone cases. Even if they only generate one sale daily per 1,000 listings, that can still be a profitable business if you’re listing hundreds of thousands of items. But whoever’s running these art theft bots found a much more profitable way of generating leads: by scanning Twitter for people specifically telling artists they’d buy a shirt with an illustration on it. The t-shirt scammers don’t have the rights to sell other people’s artwork, but they clearly don’t care. PLEASE RT: Never, ever, EVER respond to someone’s art on Twitter saying you want a shirt with that art. Bot accounts will cue into that and then pirate the artwork. This then becomes a nightmare for the artist to get the bootleg merchandise taken down. PLEASE SHARE. — Rob Schamberger (@robschamberger) December 1, 2019 Once Nana proved that this was the methodology these t-shirt sellers were using, others jumped in to subvert them. Of course, it worked. Bots will be bots. We did it. We achieved something special. Tell your grandchildren that you were THERE when this happened. Gonna mute this tweet because I'm getting WAY too many notifications, but thank you 🙏 pic.twitter.com/bkStdwOmve — Nirbion (@Nirbion) December 4, 2019 For me, this all raises two questions: Who’s responsible for this infringement? What responsibility do print-on-demand providers have to prevent infringement on their platforms? The first question is the hardest: we don’t know. These scammers are happy to continue printing shirts because their identities are well-protected, shielded by the platforms they’re working with. I reached out to Moteefe, who seems to be the worst offender for this particular strain of art theft. Countless Twitter bots are continually spamming users with newly-created Moteefe listings, as you can see in this search. Unlike most print-on-demand platforms like RedBubble, Moteefe doesn’t reveal any information about the user who created the shirt listings. They’re a well-funded startup in London, and have an obligation not to allow their platform to be exploited in this way. I’ll update if I hear back from them. Until then, be careful telling artists that you want to see their work on a shirt, unless you want dozens of scammers to use it without permission. Or feel free to use this image, courtesy of Nakanoart. So since these art-stealing bots are tracking your text and not reply images, I made this for you guys! If you want something from ANY creative made into a shirt, you can use this image to tell the artist you want to buy it. So you don’t need to type it out ❤️ pic.twitter.com/E9Mn2GILcb — nakanoart (@nakanodrawing) December 4, 2019 Update Nearly every reply to the official @Disney account on Twitter right now is someone asking for a shirt. I wonder if their social media team has figured out what’s going on yet. I know I shouldn’t buy them, but some of these copyright troll bait shirts are just amazing. Source: How Artists on Twitter Tricked Spammy T-Shirt Stores Into Admitting Their Automated Art Theft – Waxy.org

    Read at 07:00 pm, Dec 6th

  • How to fight back against Google AMP as a web user and a web developer – Marko Saric

    There’s a popular thread on Hacker News with lots of people complaining about how Google AMP (Accelerated Mobile Pages) is ruining their mobile web experience. This week I also got two AMP links sent to me via Telegram and to see those Google URLs replacing unique domain names made me a bit sad on behalf of the owners of those sites. As a site owner myself, it feels like sovereignty of a website being taken away. Other than people sharing links with me, I rarely encounter AMP in the wild. It is possible to restrict Google AMP from your life both as a web user and as a web developer. Here’s how you can fight back against Google AMP. Don't use Google search Don't use the Chrome browser Don't use AMP on your own sites Why are so many sites slow in the first place? Treat the cause: Third-party requests slow down the web How to make your sites faster than AMP without using AMP Don’t use Google search Other search engines such as Qwant and DuckDuckGo don’t rank AMP sites. So taking the step of switching from Google search to a more ethical choice removes most of the AMP touch points you might have. It’s simple to switch the default search engine in your browser of choice. You can do it in the browser settings directly. Anything other than Google will get you in the no-AMP territory. But now you might say all those non-AMP websites you visit are full of advertising, distractions and are slow to load? There’s a solution for that too. Don’t use the Chrome browser Firefox is a great browser alternative that is worth a try. Just visiting a site with Firefox’s Enhanced Tracking Protection on makes a faster and less intrusive web. It’s a built-in blocker of intrusive ads and invisible scripts. Firefox also has a Reader Mode so any site can be clutter-free even without AMP. And these features work both on Firefox for desktop and Firefox for mobile. Here’s how the Reader View looks like in Firefox Preview for Android: Don’t use AMP on your own sites Publishers and other site owners feel forced to use AMP as they fear that they’ll lose Google visibility and traffic without it. These are the forces some publishers cannot resist until more people stop using Google Chrome and search. You as a site owner or developer are a different case. I like the idea of a faster and distraction-free web but I don’t like the idea of web being controlled and molded by one company. Especially not one that is the largest advertising company in the world. This is the Googled-web Google wants to see you develop. The web “delivered by Google”. Your site being integrated with all the other cool Google products such as Analytics and AdSense. I enjoy visiting sites created by real people. The AMP pages are more boring, less diverse, less competitive, less functional and have less personality. Why are so many sites slow in the first place? The main reason AMP exists is that the sites are slow to load. But why are the sites slow to load in the first place? They feature many unnecessary third-party elements that do nothing for the user experience other than slow it all down. Google themselves will point the finger at their own analytics and ads if you use their webpage speed tests to measure the performance of your site. They even provide guides on how to make third-party resources less slow. Analytics scripts, advertising scripts, social media scripts and so much more junk. It is normal to visit a site and the majority of it is composed of unnecessary elements that you don’t see. This is why the web is so much faster with Firefox’s Enhanced Tracking Protection or with an adblocker. Firefox blocks almost 30 different trackers on a single page of Wired. It also blocks the auto-play of video and audio. This is about 30% of the total page weight. It’s important to note that Wired still gets to display their banners for people to subscribe to the magazine. As a reader, you don’t really see any difference at all in the article that you’re reading. All this content that they try to load and that is blocked by Firefox is not useful to you. Treat the cause: Third-party requests slow down the web Here are some stats: 94% of sites include at least one third-party resource 76% issue a request to an analytics domain 56% include at least one ad resource Median page requests content from 9 unique third-party domains Google owns 7 of the top 10 most popular third-party calls And what are these calls that Google owns? They’re things such as Google Analytics, Google Fonts and Google’s DoubleClick advertising scripts. Most popular third-party requests So you can see why there must be some kind of internal struggle at Google. They understand the value of a faster web but they also cannot go after the main cause of the slow web. And this is how technology such as AMP gets invented and makes things worse. We should be treating the cause of this slow web disease instead. How to make your sites faster than AMP without using AMP It’s possible to make your site faster than an AMP site without using AMP. You need to put the speed as the priority when developing. Restrict unnecessary elements. Understand every request your site is making and consider how useful they are. Do those flashing and distracting calls-to-action actually make a difference to the goals you have or are they simply annoying 99% of people that visit your site? Do you really need auto-playing videos? Restrict third-party connections and scripts. Do you actually need Google fonts? Do you need the official social media share buttons? Do you need to collect all that behavioral data that you may never look at? There are better and lighter solutions for each of these. Lazy load images and videos. There’s simply no reason to load your full page and everything on it as soon as a visitor enters your site. Lazy loading only loads images in the browser’s view and the rest only as the visitor scrolls down the page. By doing this your original site will load faster than the AMP sites. And the web experience will be better, more open and more diverse to everyone. I also tweet about things that I care about, think about and work on. If you’d like to hear more, do follow me or add your email to my occasional newsletter. Source: How to fight back against Google AMP as a web user and a web developer – Marko Saric

    Read at 04:17 pm, Dec 6th

  • A Story of a React Re-Rendering Bug

    As front-end developers, we often find ourselves getting into perplexing bugs when the page we build involves a lot of user interactions. When we find a bug, no matter how tricky it is, it means something is wrong in the code. There is no magic, and the code itself does not lie.

    Read at 02:52 pm, Dec 6th

  • Emotional baggage

    Avery felt out of place at Away. Like many of the executives at the popular direct-to-consumer luggage brand, she’d gone to an Ivy League college, worked at a popular startup, and honed an intense work ethic that set her apart from the pack.

    Read at 02:46 pm, Dec 6th

  • I Got Access to My Secret Consumer Score. Now You Can Get Yours, Too.

    Little-known companies are amassing your data — like food orders and Airbnb messages — and selling the analysis to clients. Here’s how to get a copy of what they have on you.

    Read at 02:21 pm, Dec 6th

Day of Dec 5th, 2019

  • Tsvetan Stoychev

    Hello! What's your background and what do you do? I started studying Computer Science in 2015, but I was very curious how the industry looks like and what the job market offers.

    Read at 11:59 pm, Dec 5th

  • The Case FOR ‘Latinx’: Why Intersectionality Is Not a Choice

    Over the last few years, the use of the identifier “Latinx” (pronounced “Latin-ex”), born out of a collective aim to move beyond the masculine-centric “Latino” and the gender inclusive but binary embedded “[email protected],” has received increasing attention and usage in popular

    Read at 11:55 pm, Dec 5th

  • Dependency Injection in React

    One of the challenging parts in software development is keeping code clean, maintainable and extendable. Robert C. Martin introduced five software design principles exposing the dependency management aspects of object oriented design known as SOLID.

    Read at 11:41 pm, Dec 5th

  • Razer CEO Berated And Threatened His Staff, Former Employees Say

    Min-Liang Tan was “officially pissed off,” he wrote in an email to members of Razer’s marketing team in February of 2014.

    Read at 11:39 pm, Dec 5th

  • Joe Biden Trades Barbs With Voter in Iowa: ‘You’re a Damn Liar’

    Shortly after John Kerry, the former secretary of state, endorsed Mr. Biden in the 2020 Democratic primary, the former vice president had a heated confrontation with a voter. NEW HAMPTON, Iowa — Former Vice President Joseph R. Biden Jr.

    Read at 11:26 pm, Dec 5th

  • Should You Be Allowed to Copyright a Law? We're Going to Find Out

    Copyright law, boring on its face, has posed various unprecedented threats to intellectual freedoms in recent internet history. It threatens to kill our links, kill our news, kill our memes, kill our precious videos of babies dancing to Prince.

    Read at 10:16 pm, Dec 5th

  • The Typed Object Model | CSS-Tricks

    I help write technical documentation and one feature I've been writing about this year that has really stood out is the Typed Object Model (or Typed OM). If you haven't come across it yet you would be forgiven as it's pretty new. It falls under the CSS Houdini suite of API's and on the surface seems the least exciting. However, it underpins all of them and will eventually change how we view CSS as a language. It allows for typing of values in CSS. Remember the base syntax of CSS: selector { property: value; } That value can be a lot of things, colors, units, images, words. Which to CSS makes sense, but to us, when we access it and try to change it via any means, it comes as a string. Typed OM allows that to be returned as a type instead. So if we were to access, say 10px in JavaScript, instead of '10px' being returned, we get the number 10 and the unit 'px'. Which is a whole heap easier to work with. You may have seen some of Ana Tudor's amazing demos. In her example 'Hollow', she registers custom properties in JavaScript to use in her CSS. She's using the Properties & Values API and thus can determine the types of these properties. This wouldn't be possible if Typed OM wasn't around. How about an example On the face of it, it seems a little bit more work than the way we're used to accessing and setting styles at the moment, but there are a lot of benefits. If we want to, say, get the width of an element we would do something like this: const elementWidth = getComputedStyle(myElement).width; // returns '300px' Not only are we accessing a string here, but getComputedStyle forces a re-layout. We may not be aware of what units are being used, and so accessing the numerical part of the string becomes tricky, and if we are running this in our code a number of times it could harm performance. If we want to use Typed OM and return a typed value we would have to access the properties and values via computedStyleMap() and it's get() method: const elementWidth = myElement.computedStyleMap().get('width'); // returns CSSUnitValue {value: 300, type: 'px'} Now we can access the value and the unit separately, and the value here is returned as an integer. elementWidth.value // 300 elementWidth.unit // 'px' We also haven't forced a re-layout, which is nothing short of a win. Bet you're now wondering and yes, not only can you access the CSS value as a type, but you can create unit values pretty easily as well, via the global CSS object: let newWidth = CSS.px(320); // returns CSSUnitValue {value: 320, type: 'px'} That's a small example and one that's easy to show, as the units part of the specification has been fleshed out somewhat considerably to some other value types. But regardless it allows for a lot less string matching and flexibility. Another set of values which is well specced are transform values: translate, rotate, scale, etc. This is great because if we wanted to change one of these values on an element without Typed OM, it can be tricky, especially if we've set more than one. .myElement { transform: rotate(10deg) scale(1.2); } Let's say we wanted to increase the rotation. If we access this property with getComputedStyle() a matrix is returned. With the transforms we have on the element, we can't possibly pull out one value from the matrix. I'm not going to go all vectors, scalar values, and dot product here, but suffice to say, you can't pull out one value once the matrix has been formed. There are definitely going to be numerous mappings. If you have just a transform or scale, this is possible by string matching where the value is in the matrix. But that's information for another day. We could use custom properties to set the value of these transforms and update those: .myElement { --rotate: 10deg; transform: rotate(var(--rotate)) scale(1.2); } myElement.style.setProperty('--rotate', '15deg'); However, we need to know the name of the custom property and we are still passing in a string. Enter Typed OM. Let's take a look at what's returned from the computedStyleMap: myElement.computedStyleMap().get('transform'); /* returns CSSTransformValue { 0: CSSRotate {...} 1: CSSScale {...} } */ Each transform value has its own type. There's CSSRotate and CSSScale for the above code. As well as all the others like skew and translate. So instead of dealing with matrix, or still working with strings, we can create these types and apply a CSSTransformValue with them. const newTransform = new CSSTransformValue([ new CSSRotate(CSS.deg(15)), new CSSScale(CSS.number(1.2), CSS.number(1.2)) ]) myElement.attributeStyleMap.set('transform', newTransform); Notice how we're creating the transform types with the class method and the new keyword, rather than the factory method used with the numerical values. We have a lot more control over each individual value, something much needed when we declare multiple values in CSS. I put together a Pen with all this example code here. It's the foundations As we begin to get more familiar with other API's within the Houdini suite, the benefits of all of this will become even more obvious. When we declare a new custom property with the Properties and Values API, we set a type and get automatic error handling, for instance. These value types are also passed into the worklets of the Paint API and Layout API, so we can use the power there too. There are more types I haven't mentioned, more types to come and really a lot more to write about. If it hasn't been already, Typed OM is being implemented in all major browsers at this time. It certainly piqued my interest this year, so look out for it as 2020 comes around! Source: The Typed Object Model | CSS-Tricks

    Read at 04:06 pm, Dec 5th

  • The Rising Complexity of JAMstack Sites and How to Manage Them

    When you add anything with user-generated content or dynamic data to a static site, the complexity of the build process can become comparable to launching a monolithic CMS. How can we add rich content to static sites without stitching together multiple third-party services? For people in the development community static site generators are a popular choice over traditional content management systems (CMS) like WordPress. By comparison static sites are usually lightweight, highly configurable, fast, easy to use and can be deployed almost anywhere. With static websites, no code is generated on the server; we've replaced databases and server-side code with APIs and build processes. This has become known as a JAMstack, which stands for JavaScript, APIs and Markup. I have a strong persuasion towards JAMstack sites because I feel more in control of the output than I do when working with the often large and monolithic CMSs I’ve sometimes had to use on client projects. Despite my enthusiasm, I'm often disheartened by the steep complexity curve I typically encounter about halfway through a JAMstack project. Normally the first few weeks are incredibly liberating. It's easy to get started, there is good visible progress, everything feels lean and fast. Over time, as more features are added, the build steps become more complex, multiple APIs are added, and suddenly everything feels slow. In other words, the development experience begins to suffer. It usually looks something like this: One of the reasons for this steep rise in complexity is there are limits to the type of data that markdown can easily represent. Relationships are one example where static sites struggle. Relationships between pages or collections of assets (such as an image gallery) can only be represented by markdown in inefficient ways. It requires significant preprocessing to resolve anything more complicated than a simple set or tags or categories. If you’ve ever had to do it, you will also know the authoring experience of managing relationships in markdown isn’t ideal. User-generated content is another area that can cause a steep rise in the complexity of static sites. Adding features like comments, ratings, likes or any other kind of dynamic content will require third-party services — each has its own account that needs to be managed, not to mention that adding third-party scripts can have a negative impact of page performance. If a service doesn't match your specific requirements, sometimes it’s possible to cobble solutions together using generic platforms like Google Forms or AirTable. The end result is we've outsourced the database, fragmented the content management experience and stitched together a bundle of compromises. That’s a stark contrast from the initial ease of setting up and deploying a JAMstack site. Although this complexity curve is not unique to JAMstack projects, adding rich features to markdown-driven sites is far more difficult than we care to admit. What happened!? A lack of complexity was one of the reasons we favored JAMstack in the first place. We did that thing that web developers do. We moved the complexity from one space into another and congratulated ourselves 😂. Not having complexity on the server-side is good for front-end performance, but there is little incentive to optimize any further once we do this. Ridiculous build times and complicated tool-chains have become an acceptable reality for modern front-end web development. JAMstack Plus Before I come across as sounding too critical, I should make it clear that I absolutely love static site generators. I think they are a perfect solution for many simple sites and you should still use them. However, I feel like a simple content management layer that I own and can configure is preferable to: poor content management experiences, complicated integration of third-party services, and inefficient build processes. I want to combine the benefits of a CMS with static site generators. And it seems I'm not the only one who has reached this conclusion: WordPress (et al) is often pitted _against_ static site generators. I get it. They feel like different worlds. But SSG’s just take input and make static output. You may still want/need a CMS, and WordPress can be that. It has APIs that a SSG can injest. — Chris Coyier (@chriscoyier) June 11, 2019 My encounters with static site generators lead me to the opinion that they are incredibly compelling as a way to work, but be sure you really do want a static site. Too often what I see is a messy compromise to deal with stuff a DB would make easy. — Rachel Andrew (@rachelandrew) September 20, 2019 WordPress is a fantastic and familiar content editing experience, but what if you could deploy your site statically for ultimate speed, stability, and security? ⚡️You can, and here’s a great rundown of plugins for doing headless WordPress on Netlify: https://t.co/lz6fscbX3q — Netlify (@Netlify) July 30, 2019 The solution doesn’t need to be another third-party service or require abandoning static sites entirely. You can use a personalized content management layer and unified API to enrich a static site. It might not be as hard as you think. The first step is to create an API for your site. You can use any headless CMS, but the challenge I’ve had with many options is they make a lot of assumptions about the type of content you want. You might not want the CMS to manage pages and posts, but rather use it to store comments or images. I find this particularly difficult with WordPress. I often feel like I’m forcing a blogging platform to be just the service I need. The new version of KeystoneJS (Keystone 5) is be an excellent alternative to more opinionated content management systems. It's made up of tiny independent components so you only add the parts you need. This means it doesn’t feel like modifying a blogging platform. Instead it's like creating a personalized mini-CMS and API to work specifically with your site. I call this approach JAMstack Plus. To help you get started with this idea I've created two projects: Supermaya, a starter kit for the static site generator Eleventy. Keystone JAMstack Plus, a blog enrichment platform. Introducing Supermaya The first project I want to share with you is Supermaya, an Eleventy starter kit designed to help add rich features to a blog or website without a complicated build process. It comes with the all "blog standard" features including: Posts and Pages Pagination Tags RSS feed Service worker Lazy loading images Critical CSS (if enabled) It also has considerate and accessible markup. If deployed correctly, it should get full scores on a lighthouse audit out-of-the-box: Supermaya scores 100% on Lighthouse tests. I didn’t build Supermaya specifically as a platform to add user-generated content to static sites. Instead, I started it because I was not satisfied with the way existing static site generators integrate with other build tools. That’s why all the pre-processing steps in Supermaya are built into Eleveny itself. This includes the compilation of SCSS and JavaScript. Unifying the compilation steps eliminates the need for build tools like Grunt, Gulp or Webpack running in parallel. After this, I realized the other reason for increasing complexity on JAMstack sites was integration with third-party services, usually for user-generated content. To solve this, Supermaya has optional tie-ins with a Keystone JAMstack Plus starter-kit, which makes it easier to add user-generated content and other rich features. You can deploy both Keystone and Supermaya together and connect them at the same time by following the instructions during installation. This will deploy Keystone to Herouku and Supermaya to Netlify, as well as configure your admin user and API URL. Rich features are added with progressive enhancement, so if the API cannot be reached or there is a server error, the site will continue to function without noticeable degradation or delays for users. JAMstack Plus starter kit The Keystone JAMstack Plus starter kit allows you to add rich features to a blog including: Comments Claps Reading list, and Logins Just like Supermaya, it can be used on its own. After it’s deployed, you’ll get access to an admin interface that allows you to create and manage content. You’ll also get a GraphQL endpoint that can be connected to Supermaya. It’s configured with the intention of being a headless CMS for user-generated content. It expects pages and posts to be managed by a static site generator. However, with a little work — and following the examples in Supermaya — you can connect any front-end to the GraphQL API. I’d encourage you to modify the starter-kit: Add additional features or provide content for pages directly from Keystone. If you add features that could be used by the rest of the community contribute back to the starter-kit and we can make it easier for everyone to add rich features to their sites without the need for third-party services. Note: The automatic deploy will deploy to a free instance of Heroku. This will sleep periodically if not used which can result in slow API response times after periods of inactivity. You can upgrade to a hobby instance to avoid this. Consider owning your own data JAMstack and servers are not incompatible. There’s always a server (usually multiple) — it’s just a question of who owns it. If you are using any kind of third-party service, the chances are they own your account information, your content and collect user data. Sometimes this might be an acceptable compromise compared with the overhead of deploying and managing a back-end service, but when the complexity of stitching together several APIs becomes comparable to a CMS, I believe managing a tiny configurable service that you own, can provide a better experience for users, developers and content managers. It also provides a solid platform for websites to grow beyond purely static content into more complicated and varying types of applications. I don’t think JAMstack should defined by pushing all the complexity into the front-end build process or by compromising on developer and user experience. Instead, I think JAMstack should focus on providing lean, configurable static front-ends. These can be connected to APIs to provide user-generated data and content management services. There is no reason not to own and manage these services, if it provides the best outcome. Source: The Rising Complexity of JAMstack Sites and How to Manage Them

    Read at 03:41 pm, Dec 5th

  • The argument against the use of the term “Latinx”

    As we continually search for ways to improve gender inclusivity in Spanish, we have come up with a myriad of broad language such as Latino/a and Latin@. The most recent of these solutions is the term “Latinx.

    Read at 02:40 pm, Dec 5th

  • GOP-led committee probed possible Ukraine interference in 2016 election and found nothing worth pursuing, sources say

    The Republican-controlled Senate Intelligence Committee looked into allegations that Ukraine interfered in the 2016 election and found no evidence to support the claims, according to sources familiar with the matter. CNN's Ted Barrett and Manu Raju contributed to this report.

    Read at 02:35 pm, Dec 5th

  • Did Emmanuel Macron figure out the life hack to managing Donald Trump?

    It would be safe to say that U.S. allies were just a wee bit nervous about the NATO summit in London this week. On Monday, my Post colleague Michael Birnbaum detailed the myriad ways the summit was being engineered to prevent a repeat of the less-than-perfect 2017 and 2018 summits.

    Read at 02:31 pm, Dec 5th

  • William Barr Says Those Who Don’t Show More Respect To Cops May Not Get Police Protection

    The remarks are the latest example of the U.S. attorney general's “tough on crime” approach that President Donald Trump has adopted. U.S.

    Read at 02:27 pm, Dec 5th

  • Kamala Harris’s Biggest Mistake: She Isn’t Stupidly Rich

    Kamala Harris is no longer running for president because she ran out of money. The California senator announced as much on Tuesday in a Medium post that read in part, "I’m not a billionaire. I can’t fund my own campaign.

    Read at 02:26 pm, Dec 5th

  • How McKinsey Helped the Trump Administration Carry Out Its Immigration Policies

    Newly uncovered documents show the consulting giant helped ICE find “detention savings opportunities” — including measures the agency’s staff sometimes viewed as too harsh on immigrants. This article is copublished with ProPublica, the nonprofit investigative newsroom.

    Read at 02:24 pm, Dec 5th

  • Most VPN Services are Terrible

    Short version: I strongly do not recommend using any of these providers. You are, of course, free to use whatever you like. My TL;DR advice: Roll your own and use Algo or Streisand. For messaging & voice, use Signal.

    Read at 02:11 pm, Dec 5th

  • Meet Algo, the VPN that works

    I think you’ll agree when I say: there’s no VPN option on the market designed with equal emphasis on security and ease of use. That changes now. Today we’re introducing Algo, a self-hosted personal VPN server designed for ease of deployment and security.

    Read at 02:09 pm, Dec 5th

  • When the Internet Chases You From Your Home

    On the night of Aug. 15, 2014, Zoë Quinn was out having a drink with some friends in San Francisco when her phone began to blow up with messages. Something was exploding on the internet — a strange, incoherent maelstrom of outrage that would take over her life. Ms.

    Read at 01:27 pm, Dec 5th

  • The Top Tech People to Follow on Twitter for Your Stack

    Twitter like other social media bring people together, and lots of everyday activities go on here too, people get jobs, sell, connect, work and even get items for free. This brings in the question of CROWD CONTROL.

    Read at 01:12 pm, Dec 5th

  • Our Redux Anti Pattern

    // in scoreboardReducer.js const INITIAL_STATE = { home: 0, away: 0 }; function scoreboardReducer(state = INITIAL_STATE, action) { switch(action.type) { case "INCREMENT_SCORE": { const scoringSide = action.payload; return { ...state, [scoringSide]: state[scoringSide] + 1}; } default: return state; } } //in crowdExcitmentReducer.js const INITIAL_STATE = 0; function crowdExcitementReducer(state = INITIAL_STATE, action) { switch(action.type) { case "INCREASE_CROWD_EXCITEMENT": return state + 1; default: return state; } } Source: Our Redux Anti Pattern

    Read at 03:19 am, Dec 5th

  • When a deep red town’s only grocery closed, city hall opened its own store. Just don’t call it ‘socialism.’

    BALDWIN, Fla. — When Sean Lynch ran for mayor, he never anticipated that the job would involve hiring a butcher and tracking the sale of collard greens. But in 2018, two years into his first term, the only grocery store in town shut down. People in Baldwin, Fla.

    Read at 12:14 am, Dec 5th

  • ‘Epstein Didn’t Kill Himself’ and the Meme-ing of Conspiracy

    It’s like a billboard for disillusionment and mistrust, and it’s everywhere: “Epstein didn’t kill himself.

    Read at 12:08 am, Dec 5th

  • AG Barr: Epstein’s death was a ‘perfect storm of screw-ups’

    ABOARD A US GOVERNMENT AIRCRAFT (AP) — Attorney General William Barr said he initially had his own suspicions about financier Jeffrey Epstein’s death while behind bars at one of the most secure jails in America but came to conclude that his suicide was the result of “a perfect storm of screw-u

    Read at 12:02 am, Dec 5th

  • Trump’s Crime Against America

    Over the past two weeks, a parade of sober and coldly furious civil servants has come forward to testify before Congress about President Donald Trump’s decision to withhold congressionally approved aid to Ukraine. Acting U.S.

    Read at 12:00 am, Dec 5th