PHP Internals News: Episode 76: Globals, and Phasing Out Serializable – Derick Rethans

PHP Internals News: Episode 76: Globals, and Phasing Out Serializable

In this episode of “PHP Internals News” I chat with Nikita Popov (Twitter, GitHub, Website) about two RFCs: Deprecate passing null to non-nullable arguments of internal functions, and Deprecate passing null to non-nullable arguments of internal functions.

The RSS feed for this podcast is https://derickrethans.nl/feed-phpinternalsnews.xml, you can download this episode’s MP3 file, and it’s available on Spotify and iTunes. There is a dedicated website: https://phpinternals.news

Transcript

Derick Rethans 0:14

Hi I’m Derick. Welcome to PHP internals news, a podcast dedicated to explain the latest developments in the PHP language. This is Episode 76. In this episode, I’m talking with Nikita Popov about a few more RFCs that he has been working on over the past few months. Nikita, would you please introduce yourself.

Nikita Popov 0:34

Hi, I’m Nikita. I work on PHP core development on behalf of JetBrains.

Derick Rethans 0:39

In the last few PHP releases PHP is handling of types with regards to internal functions and user land functions, has been getting closer and closer, especially with types now. But there’s still one case where type mismatches behave differently between internal and user land functions. What is this outstanding difference?

Nikita Popov 0:59

Since PHP 8.0 on the remaining difference is the handling of now. So PHP 7.0 introduced scalar types for user functions. But scalar types already existed for internal functions at that time. Unfortunately, or maybe like pragmatically, we ended up with slightly different behaviour in both cases. The difference is that user functions, don’t accept null, unless you explicitly allow it using nullable type or using a null default value. So this is the case for all user types, regardless of where or how they occur as parameter types, return values, property types, and independent if it’s an array type or integer type. For internal functions, there is this one exception where if you have a scalar type like Boolean, integer, float, or a string, and you’re not using strict types, then these arguments also accept null values silently right now. So if you have a string argument and you pass null to it, then it will simply be converted into an empty string, or for integers into zero value. At least I assume that the reason why we’re here is that the internal function behaviour existed for a long time, and the use of that behaviour was chosen to be consistent with the general behaviour of other types at the time. If you have an array type, it also doesn’t accept now and just convert it to an empty array or something silly like that. So now we are left with this inconsistency.

Derick Rethans 2:31

Is it also not possible for extensions to check whether null was passed, and then do a different behaviour like picking a default value?

Nikita Popov 2:40

That’s right, but that’s a different case. The one I’m talking about is where you have a type like string, while the one you have in mind is where you effectively have a type like string or null.

Derick Rethans 2:51

Okay.

Nikita Popov 2:52

In that case, of course, accepting null is perfectly fine.

Derick Rethans 2:56

Even though it might actually end up being different defaults.

Nikita Popov 3:01

Yeah. Nowadays we would prefer to instead, actually specify a default value. Instead of using nu

Truncated by Planet PHP, read more at the original (another 13729 bytes)

Xdebug Update: January 2021 – Derick Rethans

Xdebug Update: January 2021

Another monthly update where I explain what happened with Xdebug development in this past month. These will be published on the first Tuesday after the 5th of each month.

Patreon and GitHub supporters will get it earlier, around the first of each month.

You can become a patron or support me through GitHub Sponsors. I am currently 94% towards my $1,000 per month goal.

If you are leading a team or company, then it is also possible to support Xdebug through a subscription.

In January, I worked on Xdebug for about 60 hours, with funding being around 35 hours. I worked mostly on the following things:

Releases

The start of the month saw the release of Xdebug 3.0.2 which addresses further issues that are present in Xdebug 3.0. Xdebug 3.0.2 mainly addresses issues related to triggering features in Xdebug through Xdebug’s new modes, and a few issues related to code coverage were fixed too. Expect another bug fix release in February, as I am intending to make one release per month.

Now that the GitHub repository of the VS Code Plugin has been moved to the Xdebug organisation, there is going to be progress here too.

DBGp Client and DBGp Proxy

I have had some expert reviews of the Go code for DBGp Client and DBGp Proxy, by JetBrains developers working on their GoLand IDE. Once I have reviewed and integrated their comments I am intending to release the source code of these two tools under an open source license.

Documentation

I spent some time adding anchors throughout the documentation to make it easier to link to specific sections. The upgrade guide now also has a Japanese translation. Xdebug.org’s code has been updated to allow for translations of the documentation, although I do not have any plans to translate the rest of it at the moment. The main issue with having translations of the documentation that the translations also need updating when the original in English changes.

As part of Xdebug’s documentation efforts I created another video in my series on Xdebug 3. This new video explains Xdebug 3’s diagnostics features to help finding issues with Xdebug’s configuration and settings.

The next video that I am going to release will deal with how to trigger Xdebug’s features, such as single step debugging, profiling, and tracing.

Xdebug Cloud

The Xdebug Cloud now has a design, created by Simon Collison. With the design in place, I am currently putting the dots on the i’s related to signing up and billing. I expect to launch Xdebug Cloud for beta customers during this month.

If you want to be kept up to date with Xdebug Cloud, please sign up to the mailinglist, which I will use to send out an update not more than once a month.

PHP Internals News: Episode 74: Fibers – Derick Rethans

PHP Internals News: Episode 74: Fibers

In this episode of “PHP Internals News” I talk with Aaron Piotrowski (Twitter, Website, GitHub) about an RFC that he is proposing to add Fibers to PHP.

The RSS feed for this podcast is https://derickrethans.nl/feed-phpinternalsnews.xml, you can download this episode’s MP3 file, and it’s available on Spotify and iTunes. There is a dedicated website: https://phpinternals.news

Transcript

Derick Rethans 0:14

Hi I’m Derick. Welcome to PHP internals news, the podcast dedicated to explaining the latest developments in the PHP language. This is Episode 74. Today I’m talking with Aaron Piotrowski about a Fiber RFC, that he’s working on together with Nicolas Keller. Aaron, would you please introduce yourself.

Aaron Piotrowski 0:33

Hi everyone I’m Aaron Piotrowski, I started programming with PHP back in 1998 with PHP three, so I’ve just dated myself there but, but I’ve worked with a lot of different languages over the last few decades but PHP is always continually remaining, one of my favourite and I’m always drawn back to it. I’ve gotten a lot more involved with the PHP projects since PHP seven. The Fiber RFC is my first major contribution I have attempted though. In the past I did the RFC for the throwable exception hierarchy. And the Iterable pseudo type in PHP 7.1.

Derick Rethans 1:12

Yeah, these things are both before I started doing the podcast so hence we haven’t spoken yet, at least on here. We’ve actually met at some point in the past. I’ve had a read through the Fiber RFC this morning, but I’m still fairly baffled. Could you perhaps explain in short what Fibers are where the idea comes from. And what’s your specific interest is in adding them to PHP?

Aaron Piotrowski 1:35

A few other languages already have Fibers like Ruby, and they’re sort of similar to threads in that they contain a separate call stack, and a separate memory stack, but they differ from threads in that they exist only within a single process, and that they have to be switched to cooperatively by that process rather than actively by the OS like threads. So sometimes they’re called Green threads, and the generators that are in PHP already are actually somewhat similar to Fibers; but generators differ in that they’re stack less. And so what that means is that generator function can only be interrupted at one layer. Whereas a Fiber can be interrupted anywhere in the call stack. So like it’d be imagine if you had a generator where yield could be very deep in a function call. Rather than at the top level. Like, how generators can be used to make interruptible functions, Fibers can also be used to create similarly interruptible functions, but with again without having to know exactly when it’s going to be interrupted not at the top level but at any point in the call stack. And so the main motivation behind wanting to add this feature is to make asynchronous programming in PHP much easier and eliminate the distinction that usually exists between async code that has used promises and synchronous code that we’re all used to.

Derick Rethans 3:09

So what specifically are you proposing to ask to PHP here then?

Aaron Piotrowski 3:12

Specifically I’m looking at adding a low level Fiber API, that’s really aimed specifically at async framework authors to create their own more opinionated API’s on top of that low level API. So adds just a couple of classes: Fiber, and a FiberScheduler on within a couple of exception classes and reflection classes for inspecting Fibers. When a Fiber is suspended to the execution switch is to FiberScheduler, which is then a special Fiber, that’s able to start and resume, regular user Fibers. So a Fiber scheduler is general

Truncated by Planet PHP, read more at the original (another 18886 bytes)

Ketting support for deprecation warnings – Evert Pot

Ketting is the generic REST client for Javascript.

Version 7 is currently in beta, and will have support for Deprecation
and Sunset headers as well as deprecated links.

Deprecating Endpoints/Resources

There’s currently work done on a new internet standard:
draft-cedik-deprecation-header, a.k.a.:
“The Deprecation HTTP Header Field”.

The way this works is that the server may emit a header such as one of these:

HTTP/1.1 200 OK
Deprecation: Mon, 1 Nov 2021 00:00:00 GMT
Deprecation: true

If a server emits these, it tells the client that the endpoint should no
longer be used, or will be removed at a future date.

If specified, Ketting will now send warnings to the console via console.warn,
making it easier to spot reliance on deprecated endpoints.

The draft also defines the following additional headers:

HTTP/1.1 200 OK
Sunset: Wed, 1 Dec 2021 00:00:00 GMT
Link: </docs/update-2021>; rel="deprecation"

These headers allow a server to tell a client when the endpoint will stop
responding, and point to additional information about the depreciation.

If either of these are specified, Ketting will provide this information in
the console.

Aside from entire resources being deprecated, individual links may also get
deprecated. Given a HAL document, this may look like the following:

{ "_links": { "next": { "href": "/next-page", "hints": { "status": "deprecated" } } }
}

The format for ‘hints’ is documented in draft-nottingham-link-hint.

When you follow the next link with Ketting, Ketting will now also emit
a console warning.

// Emits warning
const nextResource = await resource.follow('next')

Want to give this a shot? Update to the latest Ketting with:

npm i ketting@beta

PHP Internals News: Episode 73: Enumerations – Derick Rethans

PHP Internals News: Episode 73: Enumerations

In this episode of “PHP Internals News” I talk with Larry Garfield (Twitter, Website, GitHub) about a new RFC that he is proposing together with Ilija Tovilo: Enumerations.

The RSS feed for this podcast is https://derickrethans.nl/feed-phpinternalsnews.xml, you can download this episode’s MP3 file, and it’s available on Spotify and iTunes. There is a dedicated website: https://phpinternals.news

Transcript

Derick Rethans 0:14

Hi I’m Derick and welcome to PHP internals news that podcast dedicated to explain the latest developments in the PHP language.

Derick Rethans 0:22

This is Episode 73. Today I’m talking with Larry Garfield, who you might recognize from hits such as object ergonomics and short functions. Larry has worked together with Ilija Tovilo on an RFC titled enumerations, and I hope that Larry will explain to me what this is all about. Larry, would you please introduce yourself?

Larry Garfield 0:43

Hello World, I’m Larry Garfield, I am director of developer experience at platform.sh. We’re a continuous deployment cloud hosting company. I’ve been in and around PHP for 20, some odd years now. And mostly as an annoying gadfly and pedant.

Derick Rethans 1:00

Well you say that but in the last few years you’ve been working together with other people on several RFCs right, so you’re not really sitting as a fly on the wall any more, you’re being actively participating now, which is why I end up talking to you now which is quite good isn’t it.

Larry Garfield 1:15

I’m not sure if the causal relationship is in that direction.

Derick Rethans 1:18

In any case we are talking about enumerations or enums today. What are enumerations or enums?

Larry Garfield 1:26

Enumerations or enums are a feature of a lot of programming languages, what they look like varies a lot depending on the language, but the basic concept is creating a type that has a fixed finite set of possible values. The classic example is Boolean; a Boolean is a type that has two and only two possible values: true and false. Enumerations are way to let you define your own types like that to say this type has two values, sort ascending or descending. This type has four values, for the four different card suits in a standard card deck, or a user can be in one of four states: pending, approved, cancelled, or active. And so those are the four possible values that this variable type can have. And what that looks like varies widely depending on the language. In a language like C or c++, it’s just a thin layer on top of integer constants, which means they get compiled away to integers at compile time and they don’t actually do all that much, they’re a little bit to help for reading. At the other end of the spectrum, you have languages like rust or Swift, where enumerations are a robust Advanced Data Type, and data construct of their own. That also supports algebraic data types, we’ll get into that a bit more later. And is a core part of how a lot of the system actually works in practice, and a lot of other languages are somewhere in the middle. Our goal with this RFC, is to give PHP more towards the advanced end of enumerations, because there are perfectly good use cases for it so let’s not cheap out on it.

Derick Rethans 3:14

What is the syntax?

Larry Garfield 3:15

Syntax we’re proposing is tied into the fact that enumerations as we’re implementing them, are a layer on top of objects, they are internally objects with some limitations on them

Truncated by Planet PHP, read more at the original (another 25388 bytes)

It all relates – Liip

“But… it all relates!” A reaction so often heard while facilitating (or participating) to group reflexion processes (brainstorming, agile retrospectives, …).

“You ask us to group things … but everything is connected!”

It often comes with a contrived smile (“things are complex, you know!”). Sometimes also with a counterproposal “let us make a single group around the central thing here which is X, since obviously all things relate to X.”

A very human reaction, which if you’re unprepared as facilitator, can take you aback. Keeping the following arguments in your mind can help.

  1. That it all relates does not mean that it all ought to conflate. It makes sense to distinguish the different aspects of a situation or a problem, the different knots of its web of complexity. Some seem to think that seeing the big picture implies refusing to distinguish the whole from its parts. Yet if we can see the links, the relationships, it is because we have identified the parts.

  2. Although a holistic view provides a definite advantage when facing a complex situation, it is good to remind ourselves that action cannot be holistic. You cannot act on the system as a whole. You may only act on precise points of the system.

Two simple arguments to help us facilitate these “everything is connected” moments and realize that in a (group) reflexion process, taking things apart is the first step towards deciding meaningful action.


Photo: Ruvande fjällripa

Svelte TypeScript Tailwind Setup – Liip

TL;DR

For the very impatient among us:

npx degit munxar/svelte-template my-svelte-project
cd my-svelte-project
npm i
npm run dev

Enjoy!

Overview

In this article I’ll give you some insights how I set up Svelte with TypeScript and style components with Tailwind. There are plenty of articles around, but I found a lot of them overcomplicate things, or don’t fit my requirements.

So here are my goals for the setup:

  • stay as close to the default template as possible, to make updates easy
  • production build should only generate css that is used
  • use typescript wherever possible

What Do I Need?

You’ll need at least some node version with npm on your machine. At time of writing I have node version 15.6.0 and npm version 7.4.0 installed on my machine.

node -v && npm -v
v15.6.0
7.4.0

Install the Svelte Default Template

To setup Svelte I open a terminal and use the command from the official Svelte homepage. TypeScript support has been already added to this template, so nothing special here.

npx degit sveltejs/template my-svelte-project
# or download and extract
cd my-svelte-project

Enable TypeScript

# enable typescript support
node scripts/setupTypeScript.js

At this point I try out if the setup works by installing all dependencies and start the development server.

# install npm dependencies
npm i
# run dev server
npm run dev

If everything worked so far, pointing my browser at http://localhost:5000 displays a friendly HELLO WORLD. Let’s stop the development server by hitting ctrl-c in the terminal.

Install Tailwind

Back in the Terminal I add Tailwind as described in their documentation.

npm install -D tailwindcss@latest postcss@latest

After this step I generate a default tailwind.config.js file with

npx tailwindcss init

If you prefer a full Tailwind config use the –full argument:
npm tailwindcss init --full
See the Tailwind documentation for more infos about this topic.

Configure Rollup to use Postcss

The default Svelte template uses Rollup as a bundler. When I run the setupTypeScript.js from the first setup step, I get the famous svelte-preprocess plugin already integrated into the rollup setup. The only thing left is that I add the config for postcss as options to the svelte-preprocess plugin. Here are the changes that I make in rollup.config.js:

// rollup.config.js (partial)
...
export default { ... plugins: [ svelte({ preprocess: sveltePreprocess({ postcss: { plugins: [require("tailwindcss")], }, }), }), ... ], ...
};

At this point Rollup should trigger postcss and therefore the Tailwind plugin. To enable it in my application, I still need one important step.

Adding a Tailwind Component to the App

Now it’s time to create a Svelte component that contains the postcss to generate all the classes. I call mine Tailwind.svelte but the name doesn’t really matter.

// src/Tailwind.svelte
<style global lang="postcss"> @tailwind base; @tailwind components; @tailwind utilities;
</style>

Some things to note here:

  • The component only has a single style element with no markup.
  • The attribute global tells the svelte-preprocess plugin to not scope the css to this component. Remember by default Svelte scopes every css to the component it was declared, in this case I don’t want this.
  • The lang=”postcss” attribute is telling svelte-preprocess to use postcss for the content. As a goody, some IDE extensions now display the content with the correct syntax highlighting for postcss.

Now use the Tailwind component in src/App.svelte

// src/App.svelte
<script lang="ts"> import Tailwind from "./Tailwind.svelte";
</script> <Tailwind />
<div class="bg-gray-200 px-4 py-2 rounded">Hello Tailwind!</div>

Now my browser displays a Tailwind styled div. Very nice!
Let’s clean up the public/i

Truncated by Planet PHP, read more at the original (another 5726 bytes)

Nimble in decision – Liip

The concept of decision entails a sense of finality. Often decisions feel like a Rodin sculpture: once for all perfectly cut. How terrible and scary is that? No wonder that many refrain from taking (major) decisions.

Can’t we remove this sense of fate and rigidity from decisions and turn decision-making into a lighter thing?

Take smaller decisions

Does that decision feel too big? What could be a smaller decision in the same direction that is safe enough to take? Find it and take it. Breaking up a big decision in a series of small decisions often helps to move forward. “One Fear at a Time”, as John Whitmore writes in Coaching for Performance.

Be it fear or decision, breaking it up in smaller pieces also allows you to adapt the course of action.

Embrace the imperfection of a decision

Make explicit the fact that the decision has been taken based on finite knowledge of a situation and thus corresponds to a local optimum. Finish any decision statement, with : ” … until we know better”.

Shouldn’t we wait then, to take better decisions? Sometimes yes. Gathering more info, giving it more thoughts is always an option. There however always comes the time when Pareto’s Law kicks in, a point beyond which an imperfect decision will show greater ROI than a more perfect one.

Make it a pilot

A great question I make use of to ease my clients in taking virtuous yet still uncertain steps: “Is it safe enough to try?” Often it is. Often, this question eases the “fear of final decision”.

So decide to try, before finally deciding– if you still believe that you will have to decide once for all.

Give it a revision date

Since a decision is made at a certain point in time in a certain context and based on finite knowledge, it seems only fair to review it later down the road, doesn’t it? Fair and definitely smart. Even more in the case of a decision declared as a temporary one, like a pilot.

Define a revision date or install the license and/or duty to revise a decision when the need or new knowledge arises.

This works particularly well for any structural or strategic decision. Imagine how fit your organization would be if every agreement in it was due to be revised! Well, the distributed governance scheme of Holacracy makes it possible for anyone to trigger revision of the governance and Sociocracy 3.0 also advocates regularly reviewing agreements.

To go one step further down the road, I dream of an organizational system where decisions that are not revised get dropped, like an expiry date for anything decided, in order to keep organizational mass as low as possible.

Embrace exceptions to the decision

Just as a local optimum will make sense for most cases around, there will be exceptions. Let them be and shine on the light of the decision. No exception should be hidden, for hiding exceptions calls to rigidify the decision even more.

On the contrary, collecting exceptions to any decision seems to me like a good practice— I yet still have to find a domain where this happens. Every exception enriches the understanding of the decision, sharpens the scope and effects of the decision, and brings material for further revision of it.

That’s all (for now) folks!

This list is not exhaustive, it simply exhausts my current thoughts on the topic. I yet decide here and now to share it with you as such. Definitely safe enough. And the digital medium gives me the license to revise it later down the road 😉

I hope this gives you a few concrete ways to take the next decision with a bit more joy and serenity.

Artwork: Stereophotography of the Grindelwald Glacier