<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://0x1.pt/feed.xml" rel="self" type="application/atom+xml" /><link href="https://0x1.pt/" rel="alternate" type="text/html" /><updated>2026-04-05T14:58:14+00:00</updated><id>https://0x1.pt/feed.xml</id><title type="html">0x1</title><subtitle>Software engineer. Built healthcare and recruitment software. Interested in finance, economics and policy.</subtitle><author><name>Vitor Sousa Pereira</name></author><entry><title type="html">The Insanity of Being a Software Engineer</title><link href="https://0x1.pt/2025/04/06/the-insanity-of-being-a-software-engineer/" rel="alternate" type="text/html" title="The Insanity of Being a Software Engineer" /><published>2025-04-06T00:00:00+00:00</published><updated>2025-04-06T00:00:00+00:00</updated><id>https://0x1.pt/2025/04/06/the-insanity-of-being-a-software-engineer</id><content type="html" xml:base="https://0x1.pt/2025/04/06/the-insanity-of-being-a-software-engineer/"><![CDATA[<p>Is something I think about often because I can’t help but wonder if most other jobs are like this.</p>

<p>Being a software engineer is tough. You need to know a couple of programming languages and tools right from the get-go. But that won’t cut it. Companies expect you to know whatever particular framework they use. That might be Rails or Django or Laravel or something else. You’ll also need CSS. It’ll take you a lifetime to learn — and you still won’t know why the layout’s breaking — but knowing just enough to get by is feasible.</p>

<p>It’s unlikely that you won’t have to deal with JavaScript. Maybe you’re lucky and you just need to sprinkle in the occasional jQuery in the legacy app you’re maintaining. But things change.</p>

<p>At some point, the people at Facebook built React. Turns out that company with tens of thousands of engineers had two specialties all along: front-end and back-end. The programming hive-mind collectively decides that React is now the right way to build software but, at the same time, companies decide they can’t afford more engineers. Lo and behold the full-stack engineer is born and you’re it. Get to learning React and building REST APIs on top of the back-end tech you already know.</p>

<p>It won’t stop there. You know you need types, right? Add TypeScript. Are you really going to be managing state in React like a pleb? Add Redux. Feeling smart because you dodged both of those? Have fun figuring out to how to configure webpack/esbuild/rollup, plus Prettier, plus ESLint.</p>

<p>“Ok”, you say. “But I can keep doing things the way that I’ve been doing them. It worked fine. I don’t need React”. Of course you can. You can absolutely deviate from the way things are done everywhere in your fast-moving, money-burning startup. Just tell your boss that you’re available to teach the new hires — who’ve only ever heard of React — about the joys of server-side rendering.</p>

<p>Oh and, turns out we were just getting started.</p>

<p>Back when dinosaurs roamed the earth there was a type of professional called a System Administrator. Their whole job was to make sure that your backend was working nicely. They handled infrastructure changes, upgrading the database, system upgrades, keeping the daemon running, restarts, everything. Then came DevOps. Some cash-strapped company somewhere decided that now all of this would be handled by the engineers and everyone agreed. Now you need to learn Docker. Oh, your whole app is just a single statically linked binary and you don’t need Docker? Learn Ansible and I hope you have fun figuring out the options you need to pass to SystemD.</p>

<p>And you’re not even halfway there. Now you gotta learn AWS. You won’t be using the GUI to configure your infrastructure like a peasant so you better learn Terraform or Pulumi or whatever.</p>

<p>You do a good job. You’re promoted to manager. You need to learn a whole other job. But that’s ok because it’s the end-game. Bliss. Here’s some of the stuff you’ll need to do:</p>

<ol>
  <li>Guesstimate deadlines</li>
  <li>Assign tasks to teammates</li>
  <li>Spec tasks</li>
  <li>Participate in annual reviews</li>
  <li>Provide valuable feedback during product meetings</li>
</ol>

<p>You better hope your company has quadrupled in number of employees by this point or you’ll be doing management plus all of the above.</p>

<p>And it can always get worse. A recruiter reached out to me a couple of days ago about an engineering position for a secret company. They decided that they required senior level skills in Rails, Hotwire and, incredibly, native mobile development. Why not add kernel and compiler development in there as well for good measure?</p>

<p>Software gets more complicated. All of this complexity is there for a reason. But what happened to specializing? When a house is being built, tons of people are involved: architects, civil engineers, plumbers, electricians, bricklayers, interior designers, roofers, surveyors, pavers, you name it. You don’t expect a single person, or even a whole single company, to be able to do all of those.</p>

<p>Maybe a future where we can build a whole app with a couple of prompts isn’t so bad.</p>]]></content><author><name>Vitor Sousa Pereira</name></author><summary type="html"><![CDATA[Is something I think about often because I can’t help but wonder if most other jobs are like this.]]></summary></entry><entry xml:lang="pt-PT"><title type="html">Leituras Recentes — Janeiro 2025</title><link href="https://0x1.pt/2025/01/04/leituras-recentes-janeiro-2025/" rel="alternate" type="text/html" title="Leituras Recentes — Janeiro 2025" /><published>2025-01-04T00:00:00+00:00</published><updated>2025-01-04T00:00:00+00:00</updated><id>https://0x1.pt/2025/01/04/leituras-recentes-janeiro-2025</id><content type="html" xml:base="https://0x1.pt/2025/01/04/leituras-recentes-janeiro-2025/"><![CDATA[<p><strong>A Intendência-Geral do Orçamento</strong> de Nuno Ivo Gonçalves – Relata a história da Intendência-Geral do Orçamento, uma instituição criada para avaliar a correcção económica das propostas de lei. A instituição foi concebida em 1929 mas nunca deixou o papel. Até hoje, as suas competências não estão atribuídas a qualquer outra instituição, para grande prejuízo da nossa economia. O livro é extraordinariamente académico e tem imensas transcrições de leis, correspondência e afins.</p>

<p><strong>Alfredo da Silva: Biografia</strong> de Miguel Figueira de Faria – Biografia do mais conhecido industrialista Português, o homem que fundou a Companhia União Fabril (CUF), a Tabaqueira, entre outras. A CUF ainda existe hoje, se bem que muito diferente. O que achei mais impressionante foi que Alfredo da Silva fundou e geriu muitas das suas empresas em tempos de grande agitação civil e política. Também as geriu à distância durante algum tempo em que esteve exilado. A leitura não é muito interessante mas gostei do livro.</p>

<p><strong>Anatomia de Uma Revolução</strong> de António Barreto – O melhor e mais interessante livro sobre o 25 de Abril que já li. Escrito por António Barreto, Ministro da Agricultura no I Governo Constitucional. O livro é escrito sempre com o foco na Reforma Agrária e dos efeitos que esta teve. Altamente recomendado.</p>

<p><strong>Autobiografia Política: Parte 1</strong> de Aníbal Cavaco Silva – Escrito pelo Prof. Cavaco Silva não muitos anos depois de ter terminado o seu Governo. Narra a sua experiência como Ministro das Finanças e do Plano no Governo de Sá Carneiro, chegada à liderança do PSD e o primeiro Governo, minoritário, que formou. Num dos capítulos, descreve a forma de funcionar do Governo e, especialmente, do Conselho de Ministros. Só por este capítulo, já merece ser lido. Os Governos do Prof. Cavaco Silva foram os mais eficientes de todos, na minha opinião. A Parte 2 está na calha de leitura.</p>

<p><strong>O Primeiro-Ministro e a Arte de Governar</strong> e <strong>Uma Experiência de Social-Democracia Moderna</strong> de Aníbal Cavaco Silva – Ambos os livros acabam por ser condensações da experiência do Prof. Cavaco Silva como Primeiro-Ministro (e talvez como Presidente da República). O primeiro livro tem uma das frases que me fez aderir ao PSD: “A crise de identidade que afeta tantos partidos, não se coloca no PSD, que não precisa de ser de direita, nem de esquerda.”</p>

<p><strong>Direito para (Quase) Todos</strong> de João Caupers - Escrito pelo antigo Presidente do Tribunal Constitucional. É uma introdução aos principais aspectos da lei portuguesa para leigos. Escrito de uma forma muito simples e acessível mas pouco interessante.</p>

<p><strong>Francisco Sá Carneiro: Solidão e Poder</strong> de Maria João Avillez – Biografia do fundador do PSD, escrita por Maria João Avillez, um monumento do jornalismo português. Descreve a vida de Francisco Sá Carneiro e de todos os seus contributos para o país, sobretudo através da fundação do PSD.</p>

<p><strong>O Equívoco do 25 de Abril</strong> de Sanchez Osório – Neste livro, publicado ainda antes do 25 de Novembro, Sanchez Osório, militar envolvido no 25 de Abril, descreve, na sua perspectiva de cristão liberal, o regime soviético que se estava a instalar. Historicamente relevante mas não expõe muitos factos relevantes que um conhecedor da história do 25 de Abril já não saiba.</p>

<p><strong>Presos Por Um Fio: Portugal e as FP-25 de Abril</strong> de Nuno Gonçalo Poças – Nuno Gonçalo Poças conta a história das Forças Populares 25 de Abril, um grupo terrorista de extrema-esquerda liderado por Otelo de Saraiva Carvalho, um dos homens do 25 de Abril. Talvez (felizmente) o único exemplo de terrorismo real, organizado na história do país. Numa tentativa de sarar as feridas do 25 de Abril e esquecer o fervor revolucionário, todos os terroristas saíram impunes e o assunto foi varrido para baixo do tapete.</p>

<p><strong>Um Caminho para Portugal</strong> de Carlos Tavares and Sara Monteiro – Escrito por Carlos Tavares, Ministro da Economia no Governo de Durão Barroso, e Sara Monteiro, economista. O livro divide-se em duas partes. Na primeira, descreve momentos que constituíram reformas reais ou oportunidades de reforma económicas. Na segunda, os autores enumeram reformas necessárias para o país retomar a convergência económica com a União Europeia. O livro é prefixado por um prefácio do ex-Ministro Miguel Cadilhe que vale a pena ler. Altamente recomendado.</p>

<!-- Local Variables: -->
<!-- jinx-languages: "pt_PT-preao" -->
<!-- End: -->]]></content><author><name>Vitor Sousa Pereira</name></author><summary type="html"><![CDATA[A Intendência-Geral do Orçamento de Nuno Ivo Gonçalves – Relata a história da Intendência-Geral do Orçamento, uma instituição criada para avaliar a correcção económica das propostas de lei. A instituição foi concebida em 1929 mas nunca deixou o papel. Até hoje, as suas competências não estão atribuídas a qualquer outra instituição, para grande prejuízo da nossa economia. O livro é extraordinariamente académico e tem imensas transcrições de leis, correspondência e afins.]]></summary></entry><entry xml:lang="pt-PT"><title type="html">Review: 25 de Novembro sem Máscara</title><link href="https://0x1.pt/2024/12/15/review-25-de-novembro-sem-mascara/" rel="alternate" type="text/html" title="Review: 25 de Novembro sem Máscara" /><published>2024-12-15T00:00:00+00:00</published><updated>2024-12-15T00:00:00+00:00</updated><id>https://0x1.pt/2024/12/15/review-25-de-novembro-sem-mascara</id><content type="html" xml:base="https://0x1.pt/2024/12/15/review-25-de-novembro-sem-mascara/"><![CDATA[<p><img src="/assets/review-25-de-novembro-sem-mascara/foto.jpg" alt="25 de Novembro sem Máscara - Capa" class="mx-auto" width="400" height="425" /></p>

<p>Em 1979, uns escassos 5 anos depois do 25 de Abril de 1974, o Alm. Pinheiro de Azevedo publicou o 25 de Novembro sem Máscara.</p>

<p>Não obstante não ser um figura histórica particularmente conhecida, Pinheiro de Azevedo esteve envolvido em praticamente todo o período revolucionário. Aderiu ao MFA e participou no 25 de Abril. Foi membro da Junta de Salvação Nacional e do Concelho da Revolução. Tomou posse como Primeiro-Ministro no VI Governo Provisório, cargo este que exercia quando se deu o 25 de Novembro.</p>

<p>O episódio mais conhecido em que esteve envolvido foi o do Cerco à Assembleia Constituinte,<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup> quando por volta de 100 000 manifestantes sequestraram o Governo e os Deputados. Terminado o cerco, o Almirante foi entrevistado e aí declarou, com uma postura praticamente casual, as palavras que o imortalizaram como o <em>Almirante sem Medo</em>:</p>

<blockquote>
  <p>Estou farto de brincadeiras (…) Fui sequestrado. Já duas vezes. Já chega, não gosto de ser sequestrado. É uma coisa que me chateia.<sup id="fnref:2"><a href="#fn:2" class="footnote" rel="footnote" role="doc-noteref">2</a></sup></p>
</blockquote>

<p>Tendo aderido ao MFA no espírito do Programa<sup id="fnref:3"><a href="#fn:3" class="footnote" rel="footnote" role="doc-noteref">3</a></sup> por este proposto, o Almirante — um moderado — manifesta-se consistentemente contra todos os exageros revolucionários e o primar da extrema-esquerda que caracterizou o período entre o 25 de Abril e o 25 de Novembro.</p>

<p>Critica a forma como a descolonização é feita, entregando o ultramar a facções satélites da União Soviética e impedindo a auto-determinação dos habitantes — o que culminou na crise dos retornados. Mostra-se contra as expropriações e nacionalizações praticadas com autorização do Governo, ambições colectivistas estas que destruíram grande parte do poder económico. É crítico da aprovação da Constituição de 1976, de inspiração soviética.</p>

<p>Mas é o 25 de Novembro que o livro, principalmente, trata. O Almirante descreve o evento como existindo sob uma “máscara hipócrita do regresso à pureza do 25 de Abril”. Interpretação esta que, hipócrita ou não, corresponde hoje, 45 anos depois, à norma.</p>

<p>Afirma que o 25 de Novembro não serviu para por termo aos excessos revolucionários mas que, pelo contrário, serviu para os legitimar.</p>

<p>A revolução já estava feita, só faltava garantir que não seria desfeita. A Constituição de 1976, escrita durante o período de domínio comunista, foi aprovada. As conquistas comunistas foram legitimadas. O 25 de Novembro derrotou o Partido Comunista e desmobilizou a frente anti-comunista que se estava a formar. O PC perdeu força mas o seu trabalho já estava feito: a descolonização, as expropriações, a Constituição.</p>

<p>Num tom mais conspiratório, alega que o 25 de Novembro terá sido executado de acordo com um plano pré-estabelecido do PC que visava eliminar facções políticas à sua esquerda. Mais ainda, acusa que o Presidente Ramalho Eanes terá sido escolhido pelas chefias do PC para por este plano em marcha – porque, alegadamente, teria simpatias comunistas.</p>

<p>Verdade ou não, o livro relata uma perspectiva diferente sobre a revolução, redigida por um dos seus intervenientes. Só por isto, merece ser lido.</p>

<p>Anotei uma passagem do livro que achei particularmente lúcida:</p>

<blockquote>
  <p>Posição típica, aliás, dos homens de esquerda: os princípios estão sempre certos, são sempre certos; na forma de actuar é que podem haver erros e a acção é que é susceptível de correcções.</p>
</blockquote>
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p><a href="https://app.parlamento.pt/comunicar/Artigo.aspx?ID=559&amp;IDSubTitulo=340">https://app.parlamento.pt/comunicar/Artigo.aspx?ID=559&amp;IDSubTitulo=340</a> <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2">
      <p><a href="https://www.youtube.com/watch?v=gqOOla0PS8M">https://www.youtube.com/watch?v=gqOOla0PS8M</a> <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:3">
      <p><a href="https://www.arquivo.presidencia.pt/viewer?id=7281&amp;FileID=315367&amp;recordType=Description">https://www.arquivo.presidencia.pt/viewer?id=7281&amp;FileID=315367&amp;recordType=Description</a> <a href="#fnref:3" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Vitor Sousa Pereira</name></author><category term="literature" /><category term="policy" /><summary type="html"><![CDATA[]]></summary></entry><entry xml:lang="pt-PT"><title type="html">Review: As Causas do Atraso Português</title><link href="https://0x1.pt/2024/05/22/review-as-causas-do-atraso-portugues/" rel="alternate" type="text/html" title="Review: As Causas do Atraso Português" /><published>2024-05-22T00:00:00+00:00</published><updated>2024-05-22T00:00:00+00:00</updated><id>https://0x1.pt/2024/05/22/review-as-causas-do-atraso-portugues</id><content type="html" xml:base="https://0x1.pt/2024/05/22/review-as-causas-do-atraso-portugues/"><![CDATA[<p><img src="/assets/review-as-causas-do-atraso-portugues/capa.png" alt="As Causas do Atraso Português - Capa" class="mx-auto" width="400" height="453" /></p>

<p>O Professor Nuno Palma, da Universidade de Manchester, escreve-nos uma versão da história económica portuguesa mais moderada, preocupada em desfazer noções e interpretações sobre o nosso passado que não são correctas.</p>

<p>Nas palavras de João Miguel Tavares, o livro é “uma máquina de triturar mitos.” Sintetizo aqui alguns daqueles que mais me disseram.</p>

<p>O primeiro, sobre o Marquês de Pombal. Um homem tido, por norma, como progressista, à frente do seu tempo e um ditador iluminado. Este deu, no entanto, início ao atraso educativo do país ao expulsar os jesuítas – que regiam a maior parte das escolas, na altura – sem implementar um sistema de ensino alternativo. Atraso educativo este do qual, ainda hoje, não recuperámos.</p>

<p>Seguindo para a Primeira República, tida como o início da nossa democracia e violentamente interrompida pelo reaccionarismo do Estado Novo. O autor descreve que estes foram anos perdidos, de regressão, onde as poucas reformas legisladas ficaram, apenas, no papel. Curiosamente, apesar de haverem eleições, haviam muito poucos eleitores elegíveis já que os analfabetos não podiam votar. Estes formavam 70% da população em 1911.</p>

<p>O capítulo sobre o Estado Novo é o mais polémico. O autor destaca que o número de analfabetos que apenas descera de 70% para 62% na Primeira República foi reduzido para 42% em 1950. Que a industrialização e convergência económica com a Europa Ocidental foram iniciadas em 1950 e que o rendimento média por pessoa subiu “de forma vertiginosa” multiplicando-se por cinco de 1926 a 1974. Que a percentagem de indivíduos que sofriam deficiências de crescimento (por causa da mal-nutrição e falta de cuidados de saúde) desceu, drasticamente, nos anos da ditadura.</p>

<p>Citando Nuno Palma, “qualquer sucesso a nível do desenvolvimento económico e dos efeitos favoráveis para o bem-estar das populações não justifica o amordaçar da liberdade.” O que é inquestionável. Igualmente inquestionável é que participar em revisionismos históricos é profundamente anti-democrático. Devemos olhar, objectivamente, para os sucessos e insucessos do Estado Novo e ambicionarmos, sempre, fazer melhor em democracia.</p>

<p>Para finalizar, destaco um último ponto – o que achei mais interessante – que é a análise que o autor faz das repercussões negativas do pendor socialista do 25 de Abril. O primeiro destes sendo a primazia, na Assembleia da República, de partidos que propõem sistemas económicos desadequados e que, dogmaticamente, rejeitam ideias alternativas. Outro, a carga negativa atribuída a termos como “liberal”, “capitalista”, “conservador” e “de direita” que são desprovidos de significado e usados como insultos para inviabilizar partidos, pessoas e ideias. Tudo isto em prejuízo das pessoas.<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup></p>

<p>O livro é extremamente legível e não há qualquer indício de academiquês. Os únicos aspectos negativos que destaco são o meta discurso, por vezes, excessivo e uma crítica demasiado constante ao status-quo da história económica e aos os seus autores – sendo, no entanto, esta crítica perfeitamente legítima.</p>
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>Parece-me que há uma luz ao fundo no túnel, no entanto, e acho que aparecimento de partidos como a Iniciativa Liberal é um indício desta mudança. Há 10 ou 20 anos, um partido com esta ideologia estaria condenado ao insucesso no sufrágio. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Vitor Sousa Pereira</name></author><category term="literature" /><category term="policy" /><summary type="html"><![CDATA[]]></summary></entry><entry xml:lang="pt-PT"><title type="html">Fundos de Pensões e PPR/OICVM</title><link href="https://0x1.pt/2024/02/25/fundos-de-pensoes-e-ppr-oicvm/" rel="alternate" type="text/html" title="Fundos de Pensões e PPR/OICVM" /><published>2024-02-25T00:00:00+00:00</published><updated>2024-02-25T00:00:00+00:00</updated><id>https://0x1.pt/2024/02/25/fundos-de-pensoes-e-ppr-oicvm</id><content type="html" xml:base="https://0x1.pt/2024/02/25/fundos-de-pensoes-e-ppr-oicvm/"><![CDATA[<p>Os Planos Poupança Reforma (PPR) são um dos investimentos de excelência a longo prazo, em Portugal, dadas as suas vantagens fiscais significativas. Existem imensos PPR à escolha e inúmeras análises destes. Não serão, no entanto, muitos os que saberão que, na verdade, a designação casual “PPR” não se refere a um mas a dois tipos de produtos diferentes: os <strong>Fundos de Pensões</strong> e os <strong>PPR/OICVM.</strong></p>

<h3 id="fundos-de-pensões">Fundos de Pensões</h3>

<ul>
  <li>Regulados pela Autoridade de Supervisão de Seguros e Fundos de Pensões (ASF).</li>
  <li>Geridos por sociedades gestoras de fundos de pensões.</li>
  <li>Só é permitido o resgate atingida a reforma ou os 60 anos de idade.<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup></li>
  <li>O resgate é feito através de pensões com periodicidade mensal. Se previsto no plano de pensões, pode ser pedido o reembolso de um terço do capital na primeira mensalidade.</li>
  <li>Taxa sobre as mais valias de 8%, no resgate.</li>
  <li>Não existe restrição no tipo dos activos constituintes do fundo.</li>
  <li>Não é possível transferir o capital para um PPR/OICVM.</li>
</ul>

<p>Resumindo, estes fundos são exclusivamente orientados para gerar poupanças para a reforma, de tal forma que nem pode ser pedido o resgate fora das condições previstas na lei.<sup id="fnref:1:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup></p>

<h3 id="planos-poupança-reformaorganismos-de-investimento-colectivo-em-valores-mobiliários-pproicvm">Planos Poupança Reforma/Organismos de Investimento Colectivo em Valores Mobiliários (PPR/OICVM)</h3>

<ul>
  <li>Regulados pela Comissão de Mercado de Valores Mobiliários (CMVM).</li>
  <li>Geridos por entidades habilitadas a gerir organismos de investimento colectivo em valores mobiliários, entre outras.</li>
  <li>Resgate permitido em qualquer altura.</li>
  <li>A totalidade do capital é reembolsada de uma só vez.</li>
  <li>Taxa sobre as mais valias de 21.5% para subscrições com menos de 5 anos, 17.2% para subscrições com mais de 5 e menos de 8 anos e 8.6% acima de 8 anos. Taxa de 8% se atingida a reforma ou os 60 anos de idade.<sup id="fnref:1:2"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup></li>
  <li>O fundo não pode investir em activos imobiliários.</li>
  <li>Não é possível transferir o capital para um fundo de pensões.</li>
</ul>

<p>Resumindo, o PPR/OICVM acaba por ser um fundo de investimento igual aos outros com a vantagem de ter um imposto sobre as mais valias significativamente inferior ao normal de 28%, em determinadas condições.</p>

<h3 id="como-é-que-consigo-saber-se-o-meu-ppr-é-um-fundo-de-pensões-ou-um-pproicvm">Como é que consigo saber se o meu “PPR” é um fundo de pensões ou um PPR/OICVM?</h3>

<p>A forma mais simples é ir à <a href="https://www.asf.com.pt/autoriza%C3%A7%C3%B5es-e-registos/fundos-de-pens%C3%B5es/entidades-autorizadas">página de pesquisa</a> de fundos de pensões no site da ASF e pesquisar pelo nome do “PPR”.</p>

<p>Em alternativa, a lei requer que a empresa que gere um fundo de pensões inclua a expressão “Sociedade Gestora de Fundos de Pensões” no nome e que um PPR/OICVM inclua, na denominação do fundo, a expressão “PPR/OICVM”.</p>

<p>Por exemplo, no <a href="https://stoik.pt/s/Regulamento-Gestao-PPR-SGF-Stoik.pdf">regulamento de gestão</a> do PPR SGF Stoik – que, confusamente, tem “PPR” no nome – pode-se confirmar que a entidade gestora se chama “Golden-SGF, Sociedade Gestora de Fundos de Pensões, S.A.”</p>

<p>Já no <a href="https://drive.google.com/file/d/1R4V5DA1GOa-MY7jEnL0GzJfHVYD0vDTR/view">documento informativo</a> do Save &amp; Grow é possível verificar que o denominação do fundo é “Save &amp; Grow PPR/OICVM - Fundo de Investimento Mobiliário Aberto de Acções de Poupança Reforma.”</p>

<h3 id="por-qual-tipo-de-ppr-devo-optar">Por qual tipo de PPR devo optar?</h3>

<p>Há determinados artigos a opinar ou que os fundos de pensões ou os PPR/OICVM são melhores porque uns ou outros têm, em média, rentabilidades superiores ou comissões mais baixas. Mas isto, como é evidente nos pontos acima indicados, não está relacionado com a <em>framework</em> legal em que o fundo opera mas apenas na qualidade da gestão do mesmo.</p>

<p>Dito isto, se o objectivo é exclusivamente investir para a reforma, praticamente que não há diferenças. Os PPR/OICVM têm uma pequena vantagem porque permitem o resgate de todo o capital de uma só vez.</p>

<p>Se o objectivo é investir mas, possivelmente, optar por um resgate mais cedo, então os PPR/OICVM são claramente o fundo mais vantajoso.</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>Excluindo aqui situações excepcionais em que o resgate é possível como desemprego de longa duração, doença grave, incapacidade permanente para o trabalho, entre outras. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a> <a href="#fnref:1:1" class="reversefootnote" role="doc-backlink">&#8617;<sup>2</sup></a> <a href="#fnref:1:2" class="reversefootnote" role="doc-backlink">&#8617;<sup>3</sup></a></p>
    </li>
  </ol>
</div>]]></content><author><name>Vitor Sousa Pereira</name></author><category term="finance" /><summary type="html"><![CDATA[Os Planos Poupança Reforma (PPR) são um dos investimentos de excelência a longo prazo, em Portugal, dadas as suas vantagens fiscais significativas. Existem imensos PPR à escolha e inúmeras análises destes. Não serão, no entanto, muitos os que saberão que, na verdade, a designação casual “PPR” não se refere a um mas a dois tipos de produtos diferentes: os Fundos de Pensões e os PPR/OICVM.]]></summary></entry><entry><title type="html">Review: Politics is for Power</title><link href="https://0x1.pt/2024/01/03/review-politics-is-for-power/" rel="alternate" type="text/html" title="Review: Politics is for Power" /><published>2024-01-03T00:00:00+00:00</published><updated>2024-01-03T00:00:00+00:00</updated><id>https://0x1.pt/2024/01/03/review-politics-is-for-power</id><content type="html" xml:base="https://0x1.pt/2024/01/03/review-politics-is-for-power/"><![CDATA[<p><img src="/assets/review-politics-is-for-power/cover.jpg" alt="Politics is for Power - Book Cover" class="mx-auto" width="300" height="453" /></p>

<p>This book made me think about what it really means to participate in politics. Not for the ones in power, but for the rest of us.</p>

<p>Eitan Hersh establishes a difference between “political hobbyism” and doing real politics.</p>

<p>Political hobbyism is what most of us do. At cafés, dinner tables and online we have really long discussions about the latest political scandals or whether a certain policy suggested by a certain party really, really fits into the party’s ideology and how we really, really don’t like that ideology. The author affirms this isn’t really doing politics because, to sum up, it achieves absolutely nothing — which I agree with.</p>

<p>How many times have you changed the way you intended to vote because a friend made a passionate and knowledgeable speech about the party or candidate they support?</p>

<p>Real politics is about acquiring power. It’s about multiplying your vote. It’s about picking a party that you think will benefit everyone the most — even if you don’t agree with everything they do — and going door to door and making it a point to help your neighbors and, as such, garner their votes.</p>

<p>This is called “deep canvassing”. It, more or less, means establishing a more personal relationship with whoever you’re trying to convince to vote your way. This is done by making the conversation personal and asking the voter for the issues they’d like to have solved instead of reciting a party-approved text from memory. The point is to establish empathy and, therefore, convince the voter to vote your way without explicitly telling them to do so because they can see that you care. Weirdly, I can’t figure out if this is actually a better, more humane and useful way to garner votes or just straight up manipulation.</p>

<p>Even more controversial is the idea that “power is derived from serving others”. On itself, this seems like a an extraordinarily democratic motto. What is really means is that providing direct services to voters will make them support you. So, you’d make health counseling, financial clinics, kindergarten and other services available to voters and have them vote for you without explicitly telling them to as you’re improving their lives.</p>

<p>Once again — on one hand, this feels like a much better way of doing politics as you’d have party cash being funneled into real services being made available to people instead of political billboards, television ads and empty speeches. On the other hand, it almost feels like paying people for their vote. “Vote for the X party and have free kindergarten and a 20% gym discount coupon.”</p>

<p>Despite the heavy topic, I’d say the book is very easy to read and would recommend it to anyone interested in politics. While the book portrays US politics, I think it applies equally as well to any established democracy.</p>]]></content><author><name>Vitor Sousa Pereira</name></author><category term="literature" /><category term="policy" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Trying out C++20’s modules with Clang and Make</title><link href="https://0x1.pt/2023/10/15/trying-out-c++20s-modules-with-clang-and-make/" rel="alternate" type="text/html" title="Trying out C++20’s modules with Clang and Make" /><published>2023-10-15T00:00:00+00:00</published><updated>2023-10-15T00:00:00+00:00</updated><id>https://0x1.pt/2023/10/15/trying-out-c++20s-modules-with-clang-and-make</id><content type="html" xml:base="https://0x1.pt/2023/10/15/trying-out-c++20s-modules-with-clang-and-make/"><![CDATA[<p><em>Edit (26/01/2024): As some people have pointed out <a href="https://news.ycombinator.com/item?id=37889631">on Hacker News</a>, the Makefile I show below fails to properly track dependencies in several scenarios. Lexi Winter has <a href="https://git.sr.ht/~lw/cxx-modules-bmake">a repository on SourceHut</a> showing how to implement correct dependency tracking with BSD Make.</em></p>

<p>Header files are a relic from the past. No modern programming language has an equivalent concept.</p>

<p>As far as I know, header files came to be because when C was built disk space was at a prime and storing libraries with their full source code would be expensive. Header files included just the necessary to be able to call into the library while being considerably smaller.</p>

<p>C++20’s modules are C++’s attempt to do away with header files and implement traditional modules like most programming languages. Both MSVC and GCC implement modules, at least partially, but I usually reach for Clang so let’s give it a try.</p>

<p>Here’s some annotated source code for a module.</p>

<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// mod1.ccm - A module. Notice the extension.</span>

<span class="c1">// Needed because we're importing headers in this module.</span>
<span class="k">module</span><span class="p">;</span>

<span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span>
<span class="c1">// Export the module with a name that matches the filename.</span>
<span class="k">export</span> <span class="k">module</span> <span class="n">mod1</span><span class="p">;</span>

<span class="c1">// Modules are orthogonal to namespaces.</span>
<span class="k">namespace</span> <span class="n">demo</span> <span class="p">{</span>

<span class="c1">// We're exporting this class with the 'export' keyword.</span>
<span class="k">export</span> <span class="k">class</span> <span class="nc">Printer</span> <span class="p">{</span>
<span class="nl">public:</span>
  <span class="kt">void</span> <span class="n">Print</span><span class="p">()</span> <span class="p">{</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Hi from the module</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span> <span class="p">}</span>
<span class="p">};</span>

<span class="p">}</span>
</code></pre></div></div>

<p>And here’s a regular source file that calls the module.</p>

<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// main.cc - A regular C++ file</span>

<span class="c1">// And here we're importing the module we defined above.</span>
<span class="k">import</span> <span class="n">mod1</span><span class="p">;</span>

<span class="k">auto</span> <span class="n">main</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kt">int</span> <span class="p">{</span>
  <span class="n">demo</span><span class="o">::</span><span class="n">Printer</span> <span class="n">printer</span><span class="p">;</span>
  <span class="n">printer</span><span class="p">.</span><span class="n">Print</span><span class="p">();</span>
  <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Finally, a <code class="language-plaintext highlighter-rouge">Makefile</code> to pull both files together.</p>

<div class="language-makefile highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">CXX</span> <span class="o">:=</span> clang++

<span class="nv">CXXFLAGS</span> <span class="o">:=</span> <span class="nt">-std</span><span class="o">=</span>c++20 <span class="nt">-fprebuilt-module-path</span><span class="o">=</span>.

<span class="nv">MODS</span> <span class="o">:=</span> mod1.ccm
<span class="nv">SRCS</span> <span class="o">:=</span> main.cc
<span class="nv">OBJS</span> <span class="o">:=</span> <span class="p">$(</span>MODS:.ccm<span class="o">=</span>.o<span class="p">)</span> <span class="p">$(</span>SRCS:.cc<span class="o">=</span>.o<span class="p">)</span>

<span class="nl">exe</span><span class="o">:</span> <span class="nf">$(OBJS)</span>
	<span class="p">$(</span>CXX<span class="p">)</span> <span class="nt">-o</span> <span class="nv">$@</span> <span class="nv">$^</span>

<span class="nl">%.o</span><span class="o">:</span> <span class="nf">%.ccm</span>
	<span class="p">$(</span>CXX<span class="p">)</span> <span class="p">$(</span>CXXFLAGS<span class="p">)</span> <span class="nt">-fmodule-output</span> <span class="nt">-c</span> <span class="nv">$&lt;</span> <span class="nt">-o</span> <span class="nv">$@</span>

<span class="nl">%.o</span><span class="o">:</span> <span class="nf">%.cc</span>
	<span class="p">$(</span>CXX<span class="p">)</span> <span class="p">$(</span>CXXFLAGS<span class="p">)</span> <span class="nt">-c</span> <span class="nv">$&lt;</span> <span class="nt">-o</span> <span class="nv">$@</span>
</code></pre></div></div>

<p>And now let’s compile and run.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ make
clang++ -std=c++20 -fprebuilt-module-path=. -fmodule-output -c mod1.ccm -o mod1.o
clang++ -std=c++20 -fprebuilt-module-path=. -c main.cc -o main.o
clang++ -o exe mod1.o main.o
$ ./exe
Hi from the module
</code></pre></div></div>

<p>We passed a couple of unfamiliar options to Clang.</p>

<p>The <code class="language-plaintext highlighter-rouge">-fmodule-output</code> option makes it generate a “Built Module Interface” as part of the compilation. This is the <code class="language-plaintext highlighter-rouge">*.pcm</code> file you now see in the build directory.</p>

<p>The <code class="language-plaintext highlighter-rouge">-fprebuilt-module-path=.</code> option passes the path to the directory that holds the <code class="language-plaintext highlighter-rouge">*.pcm</code> files.</p>

<hr />

<p>Not having to duplicate a bunch of code between header and implementation files is certainly a productivity boost. And not having to deal with <code class="language-plaintext highlighter-rouge">#pragma once</code> and include guards is very nice.</p>

<p>The compilation time for modules seems to be worse that regular translation units. This is to be expected as it’s now generating two files. I do wonder why there’s a need to generate <code class="language-plaintext highlighter-rouge">.pcm</code> files. Couldn’t their content be added to the object file in a backwards compatible manner? Still, I wouldn’t be surprised that this improves significantly as this process gets optimized.</p>

<p>What I think is a bit weird is that we now have modules and namespaces. I sort of expected that we wouldn’t need namespace anymore but it’s not the case. Modules really only handle the “import” part and not the “name disambiguation” part. It would be better if it worked more like Python’s modules.</p>

<p>Another weird part is that the standard library is currently lacking modules so you need to keep importing headers. MSVC has support for doing <code class="language-plaintext highlighter-rouge">import std.core</code> but it’s marked as experimental and doesn’t seem to work on Clang. General support for this is bound to come later.</p>

<p>Overall, despite these weird bits, C++’s modules are certainly an improvement.</p>]]></content><author><name>Vitor Sousa Pereira</name></author><category term="engineering" /><category term="c++" /><summary type="html"><![CDATA[Edit (26/01/2024): As some people have pointed out on Hacker News, the Makefile I show below fails to properly track dependencies in several scenarios. Lexi Winter has a repository on SourceHut showing how to implement correct dependency tracking with BSD Make.]]></summary></entry><entry><title type="html">Subscriber Only: A Technical Post Mortem</title><link href="https://0x1.pt/2023/08/08/subscriber-only-a-technical-post-mortem/" rel="alternate" type="text/html" title="Subscriber Only: A Technical Post Mortem" /><published>2023-08-08T00:00:00+00:00</published><updated>2023-08-08T00:00:00+00:00</updated><id>https://0x1.pt/2023/08/08/subscriber-only-a-technical-post-mortem</id><content type="html" xml:base="https://0x1.pt/2023/08/08/subscriber-only-a-technical-post-mortem/"><![CDATA[<p>Around 3 months ago, <a href="/2023/06/10/launching-subscriber-only/">I launched a service called Subscriber Only</a>. Due to lack of users, I’m shutting it down. Such is life.</p>

<p>I’m making all of the code I wrote public. Get it while it’s fresh from GitHub.</p>

<p><a href="https://github.com/subscriber-only/subscriber-only">https://github.com/subscriber-only/subscriber-only</a></p>

<p>Here’s a couple of interesting things I did and learned while working on it.</p>

<h2 id="overview">Overview</h2>

<p>Subscriber Only (SO) allows writers to tag certain posts on their Jekyll blog as gated/premium/paid and then figures out if the reader should or should not have access to the said post. It handles all the machinery needed to maintain subscriptions. It’s kind of like Substack, Patreon or OnlyFans.</p>

<p>It poses a unique challenge, when compared to the mention sites, because the content is served from the writer’s own hosting on their own domain and not a centralized place (sort-of).</p>

<p>Here’s how I went about solving this.</p>

<p>First, there’s a <a href="https://github.com/subscriber-only/jekyll-subscriber_only">Jekyll plugin</a> that hooks into the site’s build step. Every post that’s tagged with <code class="language-plaintext highlighter-rouge">subscriber_only</code> gets its content stripped and uploaded to SO’s backend.</p>

<p>Second, there’s an “agent” script that gets added to the post’s <code class="language-plaintext highlighter-rouge">&lt;head&gt;</code> – kind of like Google Analytics. This script figures out if the reader is subscribed to the site they’re currently reading and shows them either the content or a paywall with instructions on how to login or subscribe.</p>

<p>This script is, probably, the most interesting part of the whole project. Check out <a href="https://github.com/subscriber-only/subscriber-only/blob/main/public/so.js">so.js</a></p>

<p>The logic that’s associated with this script turned out to be much more complicated than I imagined. Starting with…</p>

<h2 id="cors">CORS</h2>

<p>It turns out that if you want to issue a request from <code class="language-plaintext highlighter-rouge">your-jekyll-site.com</code> to <code class="language-plaintext highlighter-rouge">app.subscriber-only.com</code> that you can’t just do it. Even if the script that’s issuing the requests is at <code class="language-plaintext highlighter-rouge">app.subscriber-only.com/so.js</code></p>

<p>SO must tell the browser which origins – domains – are allowed to issue requests to it and even which headers it accepts.</p>

<p>There’s a pretty nice gem called <a href="https://github.com/cyu/rack-cors">rack-cors</a> that let’s you configure this in a declarative way. You can find SO’s configuration in the <a href="https://github.com/subscriber-only/subscriber-only/blob/main/config/initializers/cors.rb">cors.rb initializer.</a></p>

<h2 id="poor-mans-react">Poor man’s React</h2>

<p>Another challenge was building the paywall that gets shown to the reader if they’re not subscribed.</p>

<p><img src="/assets/subscriber-only/PH_2.png" alt="Screenshot of Subscriber Only's paywall on a default Jekyll Site" width="1270" height="760" /></p>

<p>Rendering the paywall needed to not require much code as it would bloat <code class="language-plaintext highlighter-rouge">so.js</code> which would delay the script’s download and make the user experience worse. This ruled out large UI libraries like React and EJS.</p>

<p>It also needed to be better than just concatenating strings together to form some HTML because I care about developer ergonomics.</p>

<p>I settled on a <code class="language-plaintext highlighter-rouge">createElement()</code> function that looks <a href="https://react.dev/reference/react/createElement">very much like React’s</a>. I found a version of this function on Hacker News but can’t find the link.<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup> Here’s how it looks.</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">createElement</span><span class="p">(</span><span class="nx">type</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">div</span><span class="dl">"</span><span class="p">,</span> <span class="nx">props</span> <span class="o">=</span> <span class="p">{},</span> <span class="nx">children</span> <span class="o">=</span> <span class="p">[])</span> <span class="p">{</span>
  <span class="k">if </span><span class="p">(</span><span class="nx">props</span><span class="p">?.</span><span class="kd">constructor</span> <span class="o">!==</span> <span class="nb">Object</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">children</span> <span class="o">=</span> <span class="nx">props</span><span class="p">;</span>
    <span class="nx">props</span> <span class="o">=</span> <span class="p">{};</span>
  <span class="p">}</span>
  <span class="k">if </span><span class="p">(</span><span class="o">!</span><span class="nb">Array</span><span class="p">.</span><span class="nf">isArray</span><span class="p">(</span><span class="nx">children</span><span class="p">))</span> <span class="nx">children</span> <span class="o">=</span> <span class="p">[</span><span class="nx">children</span><span class="p">];</span>
  <span class="kd">const</span> <span class="nx">el</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="nx">type</span><span class="p">);</span>
  <span class="nb">Object</span><span class="p">.</span><span class="nf">assign</span><span class="p">(</span><span class="nx">el</span><span class="p">,</span> <span class="nx">props</span><span class="p">);</span>
  <span class="nb">Object</span><span class="p">.</span><span class="nf">assign</span><span class="p">(</span><span class="nx">el</span><span class="p">.</span><span class="nx">style</span><span class="p">,</span> <span class="nx">props</span><span class="p">.</span><span class="nx">style</span> <span class="o">||</span> <span class="p">{});</span>
  <span class="nx">el</span><span class="p">.</span><span class="nf">append</span><span class="p">(...</span><span class="nx">children</span><span class="p">.</span><span class="nf">filter</span><span class="p">(</span><span class="nb">Boolean</span><span class="p">));</span>
  <span class="k">return</span> <span class="nx">el</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>It takes an element type, an object of props which must map to the properties the element has and an array of children. Then it returns the element which can be placed on the DOM.</p>

<p>Here’s the function in action. It’s being used to build some placeholder sentences that get displayed while the script is running background operations.</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">e</span> <span class="o">=</span> <span class="nx">createElement</span><span class="p">;</span>

<span class="kd">function</span> <span class="nf">PlaceholderSentence</span><span class="p">(</span><span class="nx">width</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nf">e</span><span class="p">(</span><span class="dl">"</span><span class="s2">span</span><span class="dl">"</span><span class="p">,</span> <span class="p">{</span> <span class="na">style</span><span class="p">:</span> <span class="p">{</span>
    <span class="na">display</span><span class="p">:</span> <span class="dl">"</span><span class="s2">inline-block</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">minHeight</span><span class="p">:</span> <span class="dl">"</span><span class="s2">1em</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">verticalAlign</span><span class="p">:</span> <span class="dl">"</span><span class="s2">middle</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">cursor</span><span class="p">:</span> <span class="dl">"</span><span class="s2">wait</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">backgroundColor</span><span class="p">:</span> <span class="dl">"</span><span class="s2">currentColor</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">opacity</span><span class="p">:</span> <span class="p">.</span><span class="mi">5</span><span class="p">,</span>
    <span class="nx">width</span><span class="p">,</span>
  <span class="p">}});</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">PlaceholderRow</span><span class="p">(</span><span class="nx">widths</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">style</span> <span class="o">=</span> <span class="p">{</span> <span class="na">display</span><span class="p">:</span> <span class="dl">"</span><span class="s2">flex</span><span class="dl">"</span><span class="p">,</span> <span class="na">gap</span><span class="p">:</span> <span class="dl">"</span><span class="s2">8px</span><span class="dl">"</span> <span class="p">};</span>
  <span class="k">return</span> <span class="nf">e</span><span class="p">(</span><span class="dl">"</span><span class="s2">div</span><span class="dl">"</span><span class="p">,</span> <span class="p">{</span> <span class="nx">style</span> <span class="p">},</span> <span class="nx">widths</span><span class="p">.</span><span class="nf">map</span><span class="p">(</span><span class="nx">PlaceholderSentence</span><span class="p">));</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">PlaceholderText</span><span class="p">()</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">style</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">display</span><span class="p">:</span> <span class="dl">"</span><span class="s2">flex</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">flexDirection</span><span class="p">:</span> <span class="dl">"</span><span class="s2">column</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">gap</span><span class="p">:</span> <span class="dl">"</span><span class="s2">8px</span><span class="dl">"</span>
  <span class="p">};</span>

  <span class="k">return</span> <span class="nf">e</span><span class="p">(</span><span class="dl">"</span><span class="s2">div</span><span class="dl">"</span><span class="p">,</span> <span class="p">{</span> <span class="nx">style</span> <span class="p">},</span> <span class="p">[</span>
    <span class="nc">PlaceholderRow</span><span class="p">([</span><span class="dl">"</span><span class="s2">30%</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">70%</span><span class="dl">"</span><span class="p">]),</span>
    <span class="nc">PlaceholderRow</span><span class="p">([</span><span class="dl">"</span><span class="s2">10%</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">50%</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">40%</span><span class="dl">"</span><span class="p">]),</span>
    <span class="nc">PlaceholderRow</span><span class="p">([</span><span class="dl">"</span><span class="s2">40%</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">60%</span><span class="dl">"</span><span class="p">]),</span>
    <span class="nc">PlaceholderRow</span><span class="p">([</span><span class="dl">"</span><span class="s2">20%</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">40%</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">40%</span><span class="dl">"</span><span class="p">]),</span>
    <span class="nc">PlaceholderRow</span><span class="p">([</span><span class="dl">"</span><span class="s2">90%</span><span class="dl">"</span><span class="p">]),</span>
  <span class="p">]);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>I found this pretty simple and cool and plan on using it on future projects in similarly constrained environments.</p>

<h2 id="poor-mans-oauth2">Poor man’s OAuth2</h2>

<p>Then there was the matter of authentication and authorization.</p>

<p>The reader needs to be able to go to <code class="language-plaintext highlighter-rouge">your-jekyll-site.com</code> and either be shown the post’s content or a paywall with a “Subscribe” link. After they follow the link and complete the subscription process, they must be redirected back to the post and, this time, be shown its content. Next time they access the post – or any other post from that site – they must already be logged in and immediately shown the content.</p>

<p>Initially, I had thought of a very simple system. After the reader would log into <code class="language-plaintext highlighter-rouge">app.subscriber-only.com</code>, the session cookie would be set. This cookie would then be available on writer’s sites because the script using this cookie would be served from the same origin at <code class="language-plaintext highlighter-rouge">app.subscriber-only.com/so.js</code>.</p>

<p>Turns out this would have worked several years ago but no longer does. A cookie from <code class="language-plaintext highlighter-rouge">app.subscriber-only.com</code> on <code class="language-plaintext highlighter-rouge">your-jekyll-site.com</code> is considered a “third-party cookie”. These cookies are being phased out by browsers and are no longer sent with requests because they were being used by ad companies to track users across sites. This is why we can’t have nice things.</p>

<p>I ended up implementing a flow similar to OAuth2’s Authorization Code Grant<sup id="fnref:2"><a href="#fn:2" class="footnote" rel="footnote" role="doc-noteref">2</a></sup> but with less ceremony. It goes like this.</p>

<p>First, the reader clicks the “Subscribe” button on the paywall and gets redirected to <code class="language-plaintext highlighter-rouge">app.subscriber-only.com</code>. They can then create their account, input their credit card details and complete the subscription flow. At the end of the flow, they’ll have a “Go back to the post” link.</p>

<p>This link will have a <code class="language-plaintext highlighter-rouge">?code=&lt;randomly generated nonce&gt;</code> query parameter. The nonce is stored on the database and associated with the reader.</p>

<p>The <code class="language-plaintext highlighter-rouge">so.js</code> script reads the <code class="language-plaintext highlighter-rouge">code</code> from the query string and issues a request to <code class="language-plaintext highlighter-rouge">app.subscriber-only.com/api/v1/access_tokens</code> which includes the said code.</p>

<p>The code is verified to exist, deleted and an access token is returned in its stead. This access token is stored in a (first-party) cookie and passed in all further requests going out to <code class="language-plaintext highlighter-rouge">app.subscriber-only.com</code>.<sup id="fnref:3"><a href="#fn:3" class="footnote" rel="footnote" role="doc-noteref">3</a></sup></p>

<p>Unless the reader decides to clean their browser’s cookies, they’ll be authenticated from now on. The disadvantage, when compared to the naive approach I initially started with that didn’t work, is that the reader won’t be automatically authenticated if they go to <code class="language-plaintext highlighter-rouge">another-jekyll-site-using-so.com</code>.</p>

<h2 id="phoenixs-contexts-in-rails">Phoenix’s Contexts in Rails</h2>

<p>SO’s backend is written in Ruby on Rails.</p>

<p>The general Rails recommendation, when it comes to code organization, is to push all your business logic into the model and keep your controller as lean as possible. I agree with the latter part but not so much the first. You can end up with huge models, which complicates maintenance, and relying too much on Rails’ callbacks which make code flow harder to understand.</p>

<p>The usual solution to this, in the Rails world, is to use Service Objects. The usual implementation of the Service Object goes like this.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">ApplicationService</span>
  <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">call</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">block</span><span class="p">)</span>
    <span class="n">new</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">block</span><span class="p">).</span><span class="nf">call</span>
  <span class="k">end</span>
<span class="k">end</span>

<span class="k">class</span> <span class="nc">CreateUserService</span> <span class="o">&lt;</span> <span class="no">ApplicationService</span>
  <span class="k">def</span> <span class="nf">call</span><span class="p">(</span><span class="n">email</span><span class="p">)</span>
    <span class="n">user</span> <span class="o">=</span> <span class="no">User</span><span class="p">.</span><span class="nf">create!</span><span class="p">(</span><span class="n">email</span><span class="p">:)</span>
    
    <span class="no">UserMailer</span><span class="p">.</span><span class="nf">with</span><span class="p">(</span><span class="n">user</span><span class="p">:).</span><span class="nf">welcome_email</span><span class="p">.</span><span class="nf">deliver_later</span>
    
    <span class="n">user</span>
  <span class="k">end</span>
<span class="k">end</span>

<span class="c1"># Usage</span>
<span class="no">CreateUserService</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="ss">:email</span><span class="p">])</span>
</code></pre></div></div>

<p>This fits well into Ruby, it being an object-oriented language, but I find it inelegant and cumbersome as you end up with a ton of methods called <code class="language-plaintext highlighter-rouge">call</code>, classes named like methods and boilerplate inheritance.</p>

<p>The Phoenix framework – a.k.a. Elixir on Rails – has the concept of a <a href="https://hexdocs.pm/phoenix/contexts.html">Context</a>. These are pretty much the equivalent of a Service Object in a more functional language like Elixir.</p>

<p>I think Phoenix’s approach is much simpler and, if you also add in the recommended error handling strategy, you end up with more elegant and less boilerplatey code. The good news it isn’t tied to Elixir’s constructs and that is translates very easily to Ruby.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">module</span> <span class="nn">Users</span>
  <span class="kp">extend</span> <span class="nb">self</span>
  
  <span class="k">def</span> <span class="nf">create_user</span><span class="p">(</span><span class="n">email</span><span class="p">)</span>
    <span class="n">user</span> <span class="o">=</span> <span class="no">User</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">email</span><span class="p">:)</span>
    <span class="k">return</span> <span class="p">[</span><span class="ss">:invalid</span><span class="p">,</span> <span class="n">user</span><span class="p">]</span> <span class="k">if</span> <span class="n">user</span><span class="p">.</span><span class="nf">invalid?</span>
    
    <span class="no">UserMailer</span><span class="p">.</span><span class="nf">with</span><span class="p">(</span><span class="n">user</span><span class="p">:).</span><span class="nf">welcome_email</span><span class="p">.</span><span class="nf">deliver_later</span>
    
    <span class="p">[</span><span class="ss">:ok</span><span class="p">,</span> <span class="n">user</span><span class="p">]</span>
  <span class="k">end</span>
<span class="k">end</span>

<span class="c1"># Usage</span>
<span class="k">case</span> <span class="no">Users</span><span class="p">.</span><span class="nf">create_user</span><span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="ss">:email</span><span class="p">])</span>
<span class="k">in</span> <span class="p">[</span><span class="ss">:ok</span><span class="p">,</span> <span class="n">user</span><span class="p">]</span>
  <span class="o">...</span>
<span class="k">in</span> <span class="p">[</span><span class="ss">:invalid</span><span class="p">,</span> <span class="n">user</span><span class="p">]</span>
  <span class="o">...</span>
<span class="k">end</span>
</code></pre></div></div>

<p>The code is easy to understand and all of it is needed there’s not boilerplate and no yaks to shave. Better, no?</p>
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>Let me know if you did it and I’ll give you credit. Thanks! <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2">
      <p><a href="https://datatracker.ietf.org/doc/html/rfc6749#section-4.1">https://datatracker.ietf.org/doc/html/rfc6749#section-4.1</a> <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:3">
      <p>You might be wondering, like I did, why do you even need an access token and why not just pass the code in all requests. This is because the link with the code might end up being stored – in the browser’s history, for example – which makes it likelier to leak. The access token is guaranteed to only have been stored in the cookies. <a href="#fnref:3" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Vitor Sousa Pereira</name></author><category term="subscriber-only" /><category term="engineering" /><summary type="html"><![CDATA[I closed down Subscriber Only, here's a couple of interesting things I did and learned while working on it.]]></summary></entry><entry><title type="html">More Bang for Your Buck</title><link href="https://0x1.pt/2023/07/15/more-bang-for-your-buck/" rel="alternate" type="text/html" title="More Bang for Your Buck" /><published>2023-07-15T00:00:00+00:00</published><updated>2023-07-15T00:00:00+00:00</updated><id>https://0x1.pt/2023/07/15/more-bang-for-your-buck</id><content type="html" xml:base="https://0x1.pt/2023/07/15/more-bang-for-your-buck/"><![CDATA[<p>Defining an API is one of the hardest challenges a software engineer has to go through. You’ll invariably have to take several guesses in regards to how the API will be used and how it will evolve, making it as future-proof as you can, or risk having to redo it with a <code class="language-plaintext highlighter-rouge">v2</code> prefix and doubling your maintenance effort.</p>

<p>I’ve read a lot of posts on the art of API-defining but I haven’t ever read one which proposes a method, which doesn’t always work but perhaps should be implemented when it can, and which is <strong>skipping the challenge altogether and not defining an API.</strong></p>

<p>Here’s what I mean.</p>

<p>Let’s consider the most basic GET request on an MVC-style server-rendered application. There’s essentially three steps.</p>

<ol>
  <li>A request is made to <code class="language-plaintext highlighter-rouge">/resource/1</code>.</li>
  <li>The controller fetches the model with ID 1 from the database.</li>
  <li>The view takes the model and uses it to render whatever is needed.</li>
</ol>

<p>Now, here’s the same thing in a client-rendered application.</p>

<ol>
  <li>A request is made to <code class="language-plaintext highlighter-rouge">/resource/1</code>.</li>
  <li>A bundle is downloaded which includes code to both render the view and download the data needed to render it from a well-defined API endpoint.</li>
  <li>A request is made to <code class="language-plaintext highlighter-rouge">/api/resource/1</code>.</li>
  <li>The resource with ID 1 is serialized into a well-defined schema and returned to the client.</li>
  <li>The client uses the resource to render the view.</li>
</ol>

<p>Pushing aside discussions of performance and whatnot, it’s clear that we had to do more development work on the second flow. We had to sit down and define an endpoint and a schema for a resource that’s returned from that endpoint while on the first flow we didn’t have to do any of this at all.</p>

<p>Here’s another, perhaps more controversial, example.</p>

<p>Our authentication system is composed of a <code class="language-plaintext highlighter-rouge">User</code> model and an <code class="language-plaintext highlighter-rouge">AccessToken</code> model. At some point we’re required to support a new authentication flow based on passkeys and hence decide to introduce a new <code class="language-plaintext highlighter-rouge">PassKey</code> model.</p>

<p>Solution number one is just placing the <code class="language-plaintext highlighter-rouge">PassKey</code> model at the same level as the <code class="language-plaintext highlighter-rouge">AccessToken</code> one. Same thing for the logic itself.</p>

<p>Alternatively, we could modularize.</p>

<p>Should we move all models to the <code class="language-plaintext highlighter-rouge">auth</code> package? Maybe just move the models that are directly related to authentication to the new package and keep <code class="language-plaintext highlighter-rouge">User</code> in <code class="language-plaintext highlighter-rouge">app</code>. But then we can’t be having <code class="language-plaintext highlighter-rouge">app</code> call into <code class="language-plaintext highlighter-rouge">auth</code> and <code class="language-plaintext highlighter-rouge">auth</code> into <code class="language-plaintext highlighter-rouge">app</code> because that introduces a circular dependency which is bad design. So let’s make <code class="language-plaintext highlighter-rouge">auth</code> into a library and introduce a well-defined API.</p>

<p>We just put ourselves up for more work in the name of modularization, expandability and “better” software design and yet have reached the exact same end result.</p>

<p>Now, before you curse me to the fiery pits of software development hell let me be very clear: <strong>there’s good reasons for having to go through this work.</strong></p>

<p>If scale requires it, you’ll have completely separate teams handling frontend and the backend codebases. Or you’ll have a team dedicated to handling authentication code. At this point you’ll need to be spending time building APIs.</p>

<p>But this is not the case for a good chunk of software companies. So, until you really, really can’t why not just do the simple thing?</p>]]></content><author><name>Vitor Sousa Pereira</name></author><category term="engineering" /><summary type="html"><![CDATA[Skipping having to spend time defining an API until you really, really need it.]]></summary></entry><entry><title type="html">Review: Why the Germans Do it Better</title><link href="https://0x1.pt/2023/06/11/review-why-the-germans-do-it-better/" rel="alternate" type="text/html" title="Review: Why the Germans Do it Better" /><published>2023-06-11T00:00:00+00:00</published><updated>2023-06-11T00:00:00+00:00</updated><id>https://0x1.pt/2023/06/11/review-why-the-germans-do-it-better</id><content type="html" xml:base="https://0x1.pt/2023/06/11/review-why-the-germans-do-it-better/"><![CDATA[<p><img src="/assets/review-why-the-germans-do-it-better/cover.jpg" alt="Why the Germans Do it Better - Book Cover" class="mx-auto" /></p>

<p>It’s an unexpectedly interesting book.</p>

<p>Many pages are spent explaining how pervasive the effects of Nazi and the Wall eras are on current day Germany. There’s still somewhat of a, mostly mended, split between <em>Ossis</em> and <em>Wessis</em> and the right wing party <em>Alternative für Deutschland</em> stirs some troubling memories.</p>

<p>Still, what I liked the most are the aspects that – like the title says – make Germany better.</p>

<p>Always trying for consensus is one of those aspects. The German government usually rules in coalition. It tries to develop policy all parties can buy-in to. If something’s contentious, a special commission is established and asked to come back when recommendations are acceptable to all. This reminds me of the <a href="https://250bpm.com/blog:161/index.html">Swiss Political System</a>, where all parties must also reach an agreement or risk having policy overturned in popular initiatives.</p>

<p>The fact that consensus is a key point in two of the most successful European democracies speaks ill of majority governments.</p>

<p>The economic landscape of Germany is also enviable. 80% of German GDP is derived from family businesses – the <a href="https://en.wikipedia.org/wiki/Mittelstand"><em>Mittelstand</em></a>. They focus on a single product and corner the global market, “focusing relentlessly on acquiring and expanding their customer base, and making sure they stay ahead of the competition”.</p>

<p>These <em>Mittelstand</em> are based in places with less than fifty thousand inhabitants. Multinationals are spread around the country. This contrasts with most western countries where businesses are usually centralized in a few major cities. We speak a lot of desertification in Portugal. Germany’s a great role model here.</p>

<p>The relations between employees, employers and the government are also different. “Policymakers guide the market to produce maximum wealth, which is then redistributed.” Workers go on the board of the companies they serve.  Having workers on the board “proved neutral to strongly positive on all the measures of corporate success.”</p>

<p>Germans are savers and consider credit an embarrassment. All savings go to low-risk pensions and life-insurance. “Value creation is not derived through high-risk investments.” This contrasts with the VC investment model common in the US and the UK everyone else tries to copy.</p>

<p>Another interesting point is that Germans bet on employee education and it’s OK if skills acquired are disconnected from the immediate requirements of the employee – “People who work in bakeries are invited to take advanced maths in the evening”. This is incredible but I don’t really get why it happens. It seems to be that the most productive path for both employee and employer would be for the employee to become more and more specialized. The employee’s value increases, demanding higher wages, and the employer gets a more proficient worker.</p>

<p>John Kampfner sums up all of the above points in a dense sentence: “Manufacturing and engineering; exporting; solid public finances; a high skills base; social solidarity. The German way.”</p>

<p>The authors ends with a prediction: that reducing carbon emissions would be the main theme in German politics in the following years after publication (2020). That, indeed, seemed to be the case but then Russia invaded Ukraine.</p>]]></content><author><name>Vitor Sousa Pereira</name></author><category term="literature" /><category term="policy" /><summary type="html"><![CDATA[How Germany got where it's at and the effects its history have on the present.]]></summary></entry></feed>