Log in
Seblog.nl

Seblog.nl

Vim and Git

So I woke up this morning and thought: I should really dig more into using Git within Vim with tpope's vim-fugitive. So I did.

I was already using the :Gblame command it provides a lot. This command opens a vertical split, with on the right the current file and on the left for each line of that file the hash, author and date of the last time that line changed. This is great for quickly identifying the author and age of a piece of code, which helps me a great deal in understanding the purpose behind the code. It's sad that Git gives this feature a name with such a negative connotation. PHPStorm calls this 'Git annotate', which feels nicer. One can also do a git blame from the command line or on Github, but having this command right in your editor is very useful.

I noticed, however, that I can browse the commits even further, by pressing enter when the cursor was on such a line in the righthand buffer. I would instantly be lost in weird screens about commits. I also figured there would be ways to commit from Vim (what a Git plugin would it be else), but I hadn't figured out how it worked.

I think the best tour of the plugin, apart from it's help files, is this nice overview of five video's on Vimcasts.org, about the basic commands, the difference between committed files, the working copy and the index, resolving merge conflicts and other diffs, using Vim to browse Git and specificly browsing commit history. Recommended when diving into this, I learned a lot about the inner workings of Git too :)

Switched my design from using a grey background with white backgrounds for the posts, to a white background for both, and a light fading box-shadow around the posts. I am very pleased with the results!

Typing about types of types

I am switching jobs and programming languages. I already follow a few Ruby oriented podcasts, but I was looking for some new ones. So in light of that search I just listened to an episode of Remote Ruby, the one with Adam Wathan. That seemed like an especially interesting one, because Adam is a Laravel PHP developer, which is what I am now.

Later on in the episode they of course talk about Tailwind, but they start with some very interesting things about PHP and the direction it's taking. Part of the things they say are things I heard said before, but a lot of the things are things I have thought myself and now heard back.

To summarize in my own words: PHP is moving more and more towards adding types and type annotations everywhere. They are not alone in this, types are hot: in the Javascript ecosystem Typescript is growing fast, and lots of other statically typed languages grow as well. But PHP's approach is a bit odd: there is no compile step with PHP, so all your errors are still runtime errors.

I really feel more at home in the Ruby world (and Laravel, as the home of the "PHP developers who want PHP to be like Ruby"), which is why switching to Ruby made sense. But it's also a bit scary to actually join the shrinking side of the world of programming. Ruby is so dynamic, I don't see it supporting type checking anytime soon.

On the other hand, I see the value of types. I think it's valid to say that computers are getting better and better at understanding programs, and types are an important part of how they do that. I like the idea of the friendly compiler and the promises of Elm. But should that mean my PHP-code has to be full of types everywhere? Only for more specific crashes on runtime?

It was nice to hear Adam talk about this other language called Crystal, which apparently does the complete opposite of PHP: compile with static types but with as minimal type declarations as possible. That made me realise even more that my problem might not be with types, but with these annotations everywhere.


While we're on the topic of types...

Also worth noting is Elixir's take on types. Elixir, like Erlang and Ruby, is dynamically typed, and due to the nature of the runtime it's actually very hard to create a type system for it. Some smart people tried it for Erlang and failed, but wrote an article about it and afterward created this tool called Dialyzer.

Dialyzer does not run on compilation, but more as a tool on the side, during development. It looks at your code (and, in Elixir, at the types you can optionally specify), and if it's certain that your code has an error, it will complain. This means it will not catch every bug there is to catch, which is nearly impossible in such a dynamic language (I have heard the article explains why), but it will still catch some and provide value that way.

To defend PHP a bit here: this looks a lot like how my type enthusiastic co-worker uses types in PHP. His Dyalizer is called PHPStorm, and like Dyalizer it runs analysis on the code during development. This also reduces the runtime errors in the same exact way.

The point where I get the creeps, however, is the place where the type is defined. In Elixir, it's an annotation you can optionally set on a function and in the compiled code remains no trace of this hint. In PHP, the type hints are baked into the language and cluttering the real code. And they are just not that good.

For example. In Elixir you can say "the thing this function returns is a Banana, please don't look at it". The function can then actually return a string, but once you access it as a string, Dialyzer will complain, because it's a Banana, you know. In PHP, there is only strings and integers, and if you want something for yourself you got to wrap it in an object. And before you know it, there's classes everywhere, that do not really add anything more than type information.


I am not the only PHP developer, and it seems like most PHP developers are happy with the direction that is taken. It's a bit sad that due to the way things are adopted, more and more libraries and thus applications are forced into using types. Although PHP says they are optional, because they are not optional when extending classes, type declarations leak into more and more PHP code.

It was also interesting hearing Adam talk about Ruby and especially calling out Elixir as one thing he would like to explore if PHP fails him. That was sort of my plan too, but I'm actually acting on it now. I am very curious how that will turn out.

Het voelt eigenlijk best lekker om weer in UTC+2 te zitten, en dat terwijl ik theoretisch voorstander ben van afschaffen van de zomertijd i.p.v. de wintertijd. Dat is fijn, want zo heb ik bij afschaffing altijd mijn zin.

Gister suggereerde YouTube een filmpje over het snijden van een ui en ik was benieuwd dus ik klikte en nu staat er allemaal filmpjes over uisnijden voor me klaar. Help.

Match on the end of a pipe

This is a private copy of my post on the ElixirForum

So I have looked for this topic and found similar ones but not actually this one. Forgive me if I missed it.

While I really love Elixirs pipelines, I see myself writing this pattern from time to time:

def some_function(start) do
  result =
    start
    |> Enum.map(&do_something/1)
    |> Enum.filter(&but_without_these/1)

  {:ok, result}
end

For this pattern, people seem to have come up with operators that do things with second or last arguments (I found one of those discussions). I'm not really interested in that, I want to make another point.

In the above pattern, I start reading about a result, then I see start, and then the actions that lead to start. Your eyes notice the pipeline quite fast, you see what happens, but especially when the action after the pipeline is more complicated, you start asking yourself: wait, what did they call the result of this pipeline? To find out, you have to go all the way up to read the variable name.

Put in another way: this way of writing messes with the ordering in which things are happening. First, the start is evaluated, then the pipeline is run, and only after that the match is completed which gives result a value.

I think it would be nice to be able to write it like this:

def some_function(start) do
  start
  |> Enum.map(&do_something/1)
  |> Enum.filter(&but_without_these/1)
  >>> result

  {:ok, result}
end

This removes some indentation and reads nicely in order of what happens when. It might even stop the questions for |2>? You can just start a new pipeline after the first one with this variable where-ever you want.

Oh, and it's a pattern match, so it's quite powerful, as you know.

def some_function(start) do
  start
  |> Enum.map(&do_something/1)
  |> Enum.filter(&but_without_these/1)
  >>> [first | _]
  Enum.zip(start, first)
  |> Enum.reduce(&more_transforms/1)
  >>> result

  {:ok, result}
end

Note: I used >>> here because it's one of the available custom operators, but I think => would be prettier (but probably taken) or <| (but that's not available). Here's a very naive macro to make it work:

defmacro left >>> right do
  {:=, [], [right, left]}
end

Again, if this has been proposed too many times, please pardon the intrusion :)

Hoe groot is de kans

Ik keek net uit het raam en zag een geel busje langsrijden. Gewoon, een geel busje. Ik dacht aan hoe vet het zou zijn als daar een voertuig reed waarmee ik een diepe verbinding voelde. Ik zou dan denken: ha, kijk, dat voertuig, hoe groot is de kans dat ik uit mijn raam kijk en precies dat voertuig zie?

Ik had ook dit gele busje speciaal kunnen vinden, dacht ik toen. Ja, hoe groot is de kans dat ik precies uit het raam kijk als er een geel busje voorbij rijdt? Het punt is: er is altijd wel iets bijzonders dat voorbij rijdt. Hoe groot is de kans dat je uit het raam kijkt en een betekenisvolle verbinding kan leggen met datgene wat langsrijdt? Die nadert honderd procent.

Net toen ik tot die conclusie kwam, zag ik een gele takelwagen langsrijden. Nu ben je gewoon met me aan het fucken, wereld, dacht ik.

Dat je na duizenden kilometers reizen toch weer precies die ene millimeter vindt waar je sleutel perfect in past, waarna je ‘thuis’ bent.

Meer laden