1<!DOCTYPE html><html lang="en" class="scroll-smooth"><head><meta charSet="utf-8" data-next-head=""/><meta content="width=device-width, initial-scale=1" name="viewport" data-next-head=""/><meta name="twitter:card" content="summary_large_image" data-next-head=""/><meta name="twitter:site" content="https://www.ythecombinator.space/posts" data-next-head=""/><meta name="twitter:creator" content="@ythecombinator" data-next-head=""/><meta property="og:url" content="https://www.ythecombinator.space/posts" data-next-head=""/><meta property="og:locale" content="en-US" data-next-head=""/><meta property="og:site_name" content="Matheus Albuquerque" data-next-head=""/><title data-next-head="">Posts â Matheus Albuquerque</title><meta name="robots" content="index,follow" data-next-head=""/><meta name="description" content="Ideas. Stories. Updates." data-next-head=""/><meta property="og:title" content="Posts â Matheus Albuquerque" data-next-head=""/><meta property="og:description" content="Ideas. Stories. Updates." data-next-head=""/><meta property="og:type" content="website" data-next-head=""/><meta property="og:image" content="https://www.ythecombinator.space/content/posts/cover.png" data-next-head=""/><link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="manifest" href="/site.webmanifest"/><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5"/><meta name="msapplication-TileColor" content="#000000"/><meta name="theme-color" content="#000000"/><link rel="alternate" type="application/rss+xml" href="/feed.xml"/><link rel="preload" href="/_next/static/media/0c89a48fa5027cee-s.p.2cyn07wtgehh0.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><link rel="preload" href="/_next/static/media/680aa1e827d679d2-s.p.42ymt1gosxo71.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><link rel="preload" href="/_next/static/chunks/00pzj3urym6w0.css" as="style"/><link rel="preload" href="/_next/static/chunks/2gvb2we50ee4j.css" as="style"/><link rel="stylesheet" href="/_next/static/chunks/00pzj3urym6w0.css" data-n-g=""/><link rel="stylesheet" href="/_next/static/chunks/2gvb2we50ee4j.css" data-n-g=""/><noscript data-n-css=""></noscript>
1<script src="/_next/static/chunks/34wgxanerfrbm.js" defer=""></script>
1<script src="/_next/static/chunks/1b4zszah47hpf.js" defer=""></script>
1<script src="/_next/static/chunks/17dau35-rg1si.js" defer=""></script>
1<script src="/_next/static/chunks/3gemz3v50mkge.js" defer=""></script>
1<script src="/_next/static/chunks/0-6c-959uxh2y.js" defer=""></script>
1<script src="/_next/static/chunks/2ja3-z8wguc-x.js" defer=""></script>
1<script src="/_next/static/chunks/2exirh84mi4cx.js" defer=""></script>
1<script src="/_next/static/chunks/0z9h0_hnwfku6.js" defer=""></script>
1<script src="/_next/static/chunks/turbopack-2zf__bj64cl0x.js" defer=""></script>
1<script src="/_next/static/chunks/1ih71l-nwpsxb.js" defer=""></script>
1<script src="/_next/static/chunks/2b15njxz1c4-e.js" defer=""></script>
1<script src="/_next/static/chunks/1ik4958qtkqks.js" defer=""></script>
1<script src="/_next/static/chunks/1q4ksg4kzwbye.js" defer=""></script>
1<script src="/_next/static/chunks/turbopack-405ww0ojf_x8r.js" defer=""></script>
1<script src="/_next/static/mzgQ2EcaywvSCBrN7ELhT/_buildManifest.js" defer=""></script>
1<script src="/_next/static/mzgQ2EcaywvSCBrN7ELhT/_ssgManifest.js" defer=""></script>
1<script src="/_next/static/mzgQ2EcaywvSCBrN7ELhT/_clientMiddlewareManifest.js" defer=""></script>
1</head><body class="bg-white text-black antialiased dark:bg-background-color dark:text-white"><link rel="preload" as="image" imageSrcSet="/_next/image?url=%2Fcontent%2Fme%2Fexploding.png&w=48&q=75 1x, /_next/image?url=%2Fcontent%2Fme%2Fexploding.png&w=96&q=75 2x"/><div id="__next">
1<script>((e,i,s,u,m,a,l,h)=>{let d=document.documentElement,w=["light","dark"];function p(n){(Array.isArray(e)?e:[e]).forEach(y=>{let k=y==="class",S=k&&a?m.map(f=>a[f]||f):m;k?(d.classList.remove(...S),d.classList.add(a&&a[n]?a[n]:n)):d.setAttribute(y,n)}),R(n)}function R(n){h&&w.includes(n)&&(d.style.colorScheme=n)}function c(){return window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}if(u)p(u);else try{let n=localStorage.getItem(i)||s,y=l&&n==="system"?c():n;p(y)}catch(n){}})("class","theme","system",null,["light","dark"],null,true,true)</script>
1<div class="pointer-events-none z-[-1] mx-auto max-w-6xl"><div class="absolute inset-x-0 h-[200px] rounded-t-full bg-gradient-to-r from-amber-500 via-indigo-500 to-emerald-500 opacity-20 blur-3xl"></div></div><div class="m-auto max-w-2xl px-4 sm:px-6 xl:max-w-2xl xl:px-0 karla_13223893-module__zt7XhW__className karla_13223893-module__zt7XhW__variable space_grotesk_9957aa6b-module__ZewwGG__variable"><div class="flex h-screen flex-col justify-between"><header class="flex items-center py-10"><div class="flex flex-auto items-center justify-between"><div class="flex flex-1 items-center justify-between text-base leading-5"><div class="hidden sm:block"><nav aria-label="Main" data-orientation="horizontal" dir="ltr" class="relative"><div style="position:relative"><ul data-orientation="horizontal" class="flex flex-row items-center space-x-2 p-2" dir="ltr"><li class="mr-4"><a class="" data-radix-collection-item="" href="/"><img alt="Matheus Albuquerque" loading="eager" width="48" height="48" decoding="async" data-nimg="1" class="w-12 hover:animate-wave" style="color:transparent" srcSet="/_next/image?url=%2Fcontent%2Fme%2Fexploding.png&w=48&q=75 1x, /_next/image?url=%2Fcontent%2Fme%2Fexploding.png&w=96&q=75 2x" src="/_next/image?url=%2Fcontent%2Fme%2Fexploding.png&w=96&q=75"/></a></li><li><a class="link-underline dark:link-underline-black rounded-xl p-1 font-medium text-gray-900 hover:bg-gray-400/10 dark:text-gray-100 sm:p-4" data-radix-collection-item="" href="/posts">Posts</a></li><li><a class="link-underline dark:link-underline-black rounded-xl p-1 font-medium text-gray-900 hover:bg-gray-400/10 dark:text-gray-100 sm:p-4" data-radix-collection-item="" href="/talks">Talks</a></li><li><a class="link-underline dark:link-underline-black rounded-xl p-1 font-medium text-gray-900 hover:bg-gray-400/10 dark:text-gray-100 sm:p-4" data-radix-collection-item="" href="/about">About</a></li></ul></div></nav></div><button class="ml-1 flex h-11 w-11 items-center justify-center bg-transparent p-0 text-lg sm:ml-4" aria-label="Toggle Dark Mode" type="button" tabindex="0"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" aria-hidden="true" height="20" width="20" xmlns="http://www.w3.org/2000/svg"><path d="M283.211 512c78.962 0 151.079-35.925 198.857-94.792 7.068-8.708-.639-21.43-11.562-19.35-124.203 23.654-238.262-71.576-238.262-196.954 0-72.222 38.662-138.635 101.498-174.394 9.686-5.512 7.25-20.197-3.756-22.23A258.156 258.156 0 0 0 283.211 0c-141.309 0-256 114.511-256 256 0 141.309 114.511 256 256 256z"></path></svg></button></div><div class="sm:hidden"><button type="button" class="w-8 h-8 py-1 ml-1 mr-1 rounded" aria-label="Toggle Menu"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="text-gray-900 dark:text-gray-100"><path fill-rule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z" clip-rule="evenodd"></path></svg></button><div class="fixed w-full h-full top-24 right-0 bg-gray-200 dark:bg-gray-800 opacity-95 z-10 transform ease-in-out duration-300 translate-x-full"><button type="button" aria-label="toggle modal" class="fixed w-full h-full cursor-auto focus:outline-none"></button><nav class="fixed h-full mt-8"><div class="px-12 py-4"><a class="text-2xl font-bold tracking-widest text-gray-900 dark:text-gray-100" href="/">Home</a></div><div class="px-12 py-4"><a class="text-2xl font-bold tracking-widest text-gray-900 dark:text-gray-100" href="/posts">Posts</a></div><div class="px-12 py-4"><a class="text-2xl font-bold tracking-widest text-gray-900 dark:text-gray-100" href="/talks">Talks</a></div><div class="px-12 py-4"><a class="text-2xl font-bold tracking-widest text-gray-900 dark:text-gray-100" href="/about">About</a></div></nav></div></div></div></header><main class="mb-auto"><div><div class="mt-6 px-2 sm:px-0"><div class="space-y-2 pb-8 pt-6 md:space-y-5"><div class="rounded-lg"><h1 class="text-3xl font-extrabold tracking-tight sm:text-4xl md:text-6xl space_grotesk_9957aa6b-module__ZewwGG__className text-transparent bg-clip-text bg-gradient-to-r from-purple-400 to-yellow-400"><span>Ideas. Stories. Updates.</span></h1></div><div class="relative"><input aria-label="Search posts" type="text" placeholder="Search posts" class="focus:border-primary-500 focus:ring-primary-500 block w-full rounded-md border border-gray-300 bg-white px-4 py-2 text-gray-900 dark:border-gray-900 dark:bg-gray-800 dark:text-gray-100"/><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" aria-hidden="true" class="absolute right-3 top-3 h-5 w-5 text-gray-400 dark:text-gray-300" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg></div></div><!--$?--><template id="B:0"></template><!--/$--></div></div></main><footer class="mx-auto mb-8 mt-4 flex w-full flex-col items-start justify-center"><div class="pointer-events-none z-[-1] mx-auto max-w-6xl"><div class="absolute inset-x-0 h-[200px] rounded-t-full bg-gradient-to-r from-amber-500 via-indigo-500 to-emerald-500 opacity-20 blur-3xl"></div></div><hr class="mb-8 w-full border-gray-100 dark:border-gray-800"/><div class="flex w-full flex-col-reverse justify-between pb-16 sm:flex-row"><div class="flex flex-col sm:flex-row sm:space-x-16"><div class="mb-1 flex flex-row justify-center space-x-8 sm:mb-0 sm:flex-col sm:justify-start sm:space-x-0 sm:space-y-4"><a data-vt-name="vt-about-title-life" data-vt-class="title" href="/about/life">Life</a><a data-vt-name="vt-about-title-experience" data-vt-class="title" href="/about/experience">Experience</a><a href="/feed.xml">RSS</a></div><div class="mb-1 flex flex-row justify-center space-x-8 sm:mb-0 sm:flex-col sm:justify-start sm:space-x-0 sm:space-y-4"><a target="_blank" rel="noopener noreferrer" href="https://twitter.com/ythecombinator">Twitter</a><a target="_blank" rel="noopener noreferrer" href="https://github.com/ythecombinator">GitHub</a><a target="_blank" rel="noopener noreferrer" href="https://www.linkedin.com/in/ythecombinator">LinkedIn</a></div></div><p class="text-sm text-slate-500 dark:text-slate-400 mb-5 flex items-center justify-center gap-2 sm:justify-start">
1<svg width="200" viewBox="0 0 1158 91" xmlns="http://www.w3.org/2000/svg" aria-labelledby="signature" role="img"><title id="signature">Matheus Albuquerque</title><path d="M4.46 90.68c.76.32 1.62.24 2.58-.24 1.36-.72 1.92-1.62 1.68-2.7s-.68-2.1-1.32-3.06c-.48-.88-.42-1.94.18-3.18s1.1-2.18 1.5-2.82c1.52-2.56 3.3-4.88 5.34-6.96s4.1-4.12 6.18-6.12c5.04-4.56 10.3-8.86 15.78-12.9s11.1-7.98 16.86-11.82C64.76 33.2 76.84 26 89.48 19.28c2.16-1.12 4.48-2.34 6.96-3.66s5.02-2.58 7.62-3.78 5.24-2.26 7.92-3.18 5.3-1.5 7.86-1.74c-1.6 4.08-3.74 7.88-6.42 11.4l-7.86 10.32c-3.12 4.08-6.28 8.06-9.48 11.94s-6.44 7.82-9.72 11.82c-.96 1.12-2.1 2.4-3.42 3.84s-2.58 2.96-3.78 4.56-2.26 3.22-3.18 4.86-1.42 3.26-1.5 4.86c-.16 1.84.2 3.06 1.08 3.66s1.96.82 3.24.66 2.58-.52 3.9-1.08 2.34-1.08 3.06-1.56c4.16-2.48 8.22-5.18 12.18-8.1s7.86-5.9 11.7-8.94l11.52-9.12c3.84-3.04 7.72-6 11.64-8.88 3.84-2.8 7.74-5.56 11.7-8.28s8.14-5 12.54-6.84c.48-.16.98-.34 1.5-.54s1.1-.38 1.74-.54c-.88 2.4-2.14 4.7-3.78 6.9s-3.18 4.3-4.62 6.3c-2.24 3.12-4.5 6.22-6.78 9.3s-4.54 6.14-6.78 9.18l-2.64 3.3c-1.12 1.4-2.3 2.96-3.54 4.68s-2.4 3.52-3.48 5.4-1.88 3.7-2.4 5.46-.66 3.4-.42 4.92 1.08 2.76 2.52 3.72c1.2.88 2.58 1.28 4.14 1.2s3.02-.28 4.38-.6c3.36-.8 6.6-1.86 9.72-3.18s6.24-2.66 9.36-4.02c2.4-1.04 4.9-2.22 7.5-3.54s5.24-2.56 7.92-3.72 5.4-2.14 8.16-2.94 5.5-1.2 8.22-1.2c1.2-.08 2.04-.48 2.52-1.2s.66-1.5.54-2.34-.52-1.6-1.2-2.28-1.62-.98-2.82-.9c-2.88.16-5.7.68-8.46 1.56s-5.46 1.88-8.1 3c-3.12 1.2-6.24 2.52-9.36 3.96s-6.24 2.82-9.36 4.14-6.26 2.54-9.42 3.66-6.38 2-9.66 2.64c.08-.72.3-1.52.66-2.4s.8-1.74 1.32-2.58 1.04-1.64 1.56-2.4.94-1.38 1.26-1.86c2.16-3.44 4.44-6.8 6.84-10.08 2.56-3.6 5.18-7.1 7.86-10.5s5.3-6.9 7.86-10.5c.72-.96 1.7-2.26 2.94-3.9s2.32-3.36 3.24-5.16 1.48-3.56 1.68-5.28-.38-3.18-1.74-4.38c-.88-.8-1.86-1.22-2.94-1.26s-2.18.02-3.3.18c-2.64.4-5.18 1.24-7.62 2.52s-4.82 2.6-7.14 3.96c-4.08 2.48-8.02 5.1-11.82 7.86s-7.62 5.54-11.46 8.34c-3.92 2.96-7.76 5.9-11.52 8.82s-7.56 5.86-11.4 8.82c-2.24 1.68-4.58 3.58-7.02 5.7s-4.98 3.94-7.62 5.46c.8-1.12 1.62-2.2 2.46-3.24S88.2 60.4 89 59.36c1.6-2.16 3.26-4.3 4.98-6.42s3.42-4.26 5.1-6.42c3.44-4.24 6.86-8.44 10.26-12.6s6.7-8.48 9.9-12.96l2.343-3.124.537-.716c1.2-1.6 2.28-3.3 3.24-5.1s1.6-3.58 1.92-5.34-.08-3.32-1.2-4.68c-.64-.8-1.42-1.32-2.34-1.56s-1.88-.34-2.88-.3-2.02.16-3.06.36-1.92.42-2.64.66C108.12 3 101.3 5.58 94.7 8.9s-13.06 6.78-19.38 10.38A411.126 411.126 0 0 0 39.2 42.2c-5.36 3.84-10.64 7.84-15.84 12S13.32 62.92 8.84 67.88c-.96 1.04-1.96 2.18-3 3.42s-1.98 2.56-2.82 3.96-1.5 2.84-1.98 4.32-.68 2.98-.6 4.5c.08.72.28 1.56.6 2.52s.78 1.8 1.38 2.52 1.28 1.24 2.04 1.56zm205.77-20.095.45-.005c1.36-.04 2.72-.22 4.08-.54s2.68-.72 3.96-1.2 2.48-.92 3.6-1.32c2.4-.8 4.84-1.74 7.32-2.82s5-1.82 7.56-2.22c.72-.08 1.36-.36 1.92-.84s.96-1.02 1.2-1.62.28-1.22.12-1.86-.6-1.24-1.32-1.8c-.88-.64-1.82-.84-2.82-.6s-1.94.48-2.82.72c-1.6.48-3.26 1.08-4.98 1.8s-3.46 1.44-5.22 2.16-3.54 1.36-5.34 1.92-3.58.96-5.34 1.2c.64-1.12.92-2.18.84-3.18s-.92-1.94-2.52-2.82c-1.6-.64-3.2-.88-4.8-.72-.24-.24-.52-.46-.84-.66s-.68-.38-1.08-.54c-1.84-.56-3.72-.94-5.64-1.14s-3.88-.18-5.88.06c-1.2.16-2.72.58-4.56 1.26s-3.54 1.56-5.1 2.64-2.72 2.36-3.48 3.84-.7 3.06.18 4.74c.72 1.36 1.8 2.16 3.24 2.4s2.84.24 4.2 0c2.08-.4 4.14-1 6.18-1.8s4.1-1.52 6.18-2.16c1.6-.48 3.2-.84 4.8-1.08-.4 1.12-.42 2.18-.06 3.18s1.22 1.82 2.58 2.46c1.2.4 2.48.58 3.84.54zm-21.87-7.865c1.28-.72 2.88-1.2 4.8-1.44-.8.32-1.6.6-2.4.84s-1.6.44-2.4.6zm48.24 8.64c2.4.08 4.8-.36 7.2-1.32s4.64-1.88 6.72-2.76c1.04-.4 2.58-1.06 4.62-1.98s4.22-2.06 6.54-3.42c-.56.8-1 1.62-1.32 2.46s-.32 1.7 0 2.58c.4 1.04 1.04 1.74 1.92 2.1s1.76.5 2.64.42c2.48-.24 4.9-.76 7.26-1.56s4.7-1.52 7.02-2.16c2.88-.72 5.76-1.32 8.64-1.8h1.44c-.64.88-1 1.76-1.08 2.64s.56 1.84 1.92 2.88c.64.4 1.24.64 1.8.72 1.44.32 2.96.26 4.56-.18s3.08-.86 4.44-1.26c2.64-.8 5.28-1.62 7.92-2.46s5.32-1.66 8.04-2.46c.56-.16 1.32-.3 2.28-.42s1.92-.3 2.88-.54 1.8-.58 2.52-1.02 1.2-1.02 1.44-1.74c.32-1.12.3-1.98-.06-2.58s-.9-1.02-1.62-1.26-1.54-.34-2.46-.3-1.7.14-2.34.3c-2.4.48-4.76 1.1-7.08 1.86s-4.64 1.5-6.96 2.22c-1.2.4-2.46.84-3.78 1.32s-2.66.92-4.02 1.32c.4-.8.48-1.64.24-2.52-.32-1.36-1.24-2.32-2.76-2.88-1.2-.48-2.5-.7-3.9-.66s-2.78.2-4.14.48-2.72.62-4.08 1.02-2.64.72-3.84.96c-1.36.4-2.86.88-4.5 1.44s-3.3 1.04-4.98 1.44c1.04-1.2 2.1-2.34 3.18-3.42s2.1-2.18 3.06-3.3l5.52-5.76c1.84-1.92 3.72-3.8 5.64-5.64 3.36-3.28 6.8-6.5 10.32-9.66s7.28-5.9 11.28-8.22c.72-.48 1.18-1.14 1.38-1.98s.1-1.62-.3-2.34c-.72-1.12-1.62-1.58-2.7-1.38s-2.06.62-2.94 1.26c-2.16 1.44-4.28 3-6.36 4.68s-4.12 3.4-6.12 5.16c-3.28 2.8-6.5 5.7-9.66 8.7s-6.26 6.06-9.3 9.18c-2.4 1.6-5 3.14-7.8 4.62s-5.64 2.86-8.52 4.14-5.8 2.44
1-8.76 3.48-5.84 1.84-8.64 2.4c2.08-4.16 4.94-8.04 8.58-11.64s7.1-6.96 10.38-10.08l1.2-1.08c1.2 0 2.48.1 3.84.3s2.56.5 3.6.9c.4.8.98 1.3 1.74 1.5s1.5.16 2.22-.12 1.32-.76 1.8-1.44.6-1.5.36-2.46c-.32-1.12-.86-1.96-1.62-2.52s-1.62-.96-2.58-1.2c-1.04-.32-2.16-.48-3.36-.48 2.32-2.16 4.68-4.26 7.08-6.3s4.84-4.1 7.32-6.18c.56-.56.88-1.2.96-1.92s-.04-1.38-.36-1.98-.78-1.04-1.38-1.32-1.3-.3-2.1-.06c-1.44.4-2.86 1.34-4.26 2.82s-2.62 2.7-3.66 3.66c-2.16 1.84-4.28 3.68-6.36 5.52s-4.16 3.72-6.24 5.64c-9.92.16-19.96.58-30.12 1.26S206 39.24 196.4 41.72c-.8.24-1.22.78-1.26 1.62s.38 1.42 1.26 1.74c.4.16.84.16 1.32 0s.92-.28 1.32-.36c1.68-.4 3.34-.7 4.98-.9s3.3-.42 4.98-.66c4.64-.48 9.26-.86 13.86-1.14s9.22-.5 13.86-.66c2.32-.08 4.6-.12 6.84-.12h6.84l-1.68 1.68c-.48.48-1.48 1.5-3 3.06s-3.18 3.38-4.98 5.46-3.5 4.26-5.1 6.54-2.78 4.4-3.54 6.36-.86 3.58-.3 4.86 2.16 2 4.8 2.16zm94.5-1.2c1.4.16 2.8.2 4.2.12s2.74-.2 4.02-.36c4.88-.48 9.68-1.22 14.4-2.22s9.48-2.06 14.28-3.18c1.84-.4 3.66-.82 5.46-1.26s3.62-.74 5.46-.9c1.36-.08 2.26-.48 2.7-1.2s.54-1.5.3-2.34-.76-1.58-1.56-2.22-1.8-.92-3-.84c-2.8.32-5.58.82-8.34 1.5s-5.54 1.34-8.34 1.98c-3.84.88-7.7 1.72-11.58 2.52s-7.78 1.36-11.7 1.68h-1.74c-.92 0-1.92-.04-3-.12s-2.1-.22-3.06-.42-1.6-.46-1.92-.78c.96.16 2.08.3 3.36.42s2.52.12 3.72 0 2.28-.38 3.24-.78 1.68-1.08 2.16-2.04c.56-1.28.62-2.34.18-3.18s-1.22-1.5-2.34-1.98-2.44-.76-3.96-.84-3.04-.04-4.56.12-2.9.42-4.14.78-2.14.82-2.7 1.38c-.88.8-1.48 1.7-1.8 2.7s-.42 2.02-.3 3.06.44 2.04.96 3 1.22 1.8 2.1 2.52c1.04.88 2.2 1.54 3.48 1.98s2.62.74 4.02.9zm67.86.12c2.72 0 5.42-.36 8.1-1.08s5.34-1.54 7.98-2.46 5.3-1.8 7.98-2.64 5.38-1.38 8.1-1.62c.8 0 1.48-.24 2.04-.72s.94-1.04 1.14-1.68.22-1.3.06-1.98-.6-1.26-1.32-1.74c-.56-.4-1.2-.62-1.92-.66s-1.46.02-2.22.18-1.52.36-2.28.6-1.42.44-1.98.6c-2.24.56-4.44 1.14-6.6 1.74s-4.36 1.22-6.6 1.86l-5.88 1.8c.32-.56.46-1.16.42-1.8s-.38-1.36-1.02-2.16c-.88-.88-1.94-1.32-3.18-1.32s-2.42.12-3.54.36c-1.28.4-2.64.92-4.08 1.56s-2.9 1.26-4.38 1.86-2.96 1.1-4.44 1.5-2.94.6-4.38.6c.72-.88 1.3-1.76 1.74-2.64s.26-1.88-.54-3-1.96-1.68-3.48-1.68c-1.2.08-2.08.52-2.64 1.32s-.76 1.64-.6 2.52c-.64.96-1.18 1.96-1.62 3s-.62 2.02-.54 2.94.48 1.72 1.2 2.4 1.88 1.14 3.48 1.38c2.56.4 5.22.2 7.98-.6s5.5-1.72 8.22-2.76c0 1.12.48 2.12 1.44 3 .8.88 1.92 1.32 3.36 1.32zm40.8 2.82c1.04.04 2.14-.14 3.3-.54s2.32-.9 3.48-1.5 2.1-1.02 2.82-1.26c5.04-1.68 10.18-3.12 15.42-4.32s10.5-2.12 15.78-2.76c.96-.16 2.06-.2 3.3-.12s2.26-.2 3.06-.84c.56-.4.94-.88 1.14-1.44s.24-1.14.12-1.74-.36-1.14-.72-1.62-.86-.84-1.5-1.08c-1.2-.32-2.56-.46-4.08-.42s-3.08.22-4.68.54-3.16.66-4.68 1.02-2.84.66-3.96.9c-2.48.56-5.24 1.18-8.28 1.86s-6.04 1.46-9 2.34c-.4-1.28-1.34-2.14-2.82-2.58s-3.14-.76-4.98-.96-3.68-.42-5.52-.66-3.28-.8-4.32-1.68c-.72-.56-1.48-.78-2.28-.66s-1.48.44-2.04.96-.84 1.22-.84 2.1.48 1.8 1.44 2.76c.64.72 1.48 1.26 2.52 1.62s2.12.64 3.24.84 2.24.36 3.36.48 2.12.26 3 .42c-.8.24-1.56.58-2.28 1.02s-1.34.96-1.86 1.56-.84 1.26-.96 1.98.02 1.48.42 2.28c.56.96 1.36 1.46 2.4 1.5zm158.88 16.14c1.44.24 2.82.32 4.14.24s2.52-.42 3.6-1.02 1.74-1.66 1.98-3.18.64-2.94 1.2-4.26 1.16-2.66 1.8-4.02c1.28-2.64 2.6-5.24 3.96-7.8s2.76-5.12 4.2-7.68l31.08.48c.64 0 1.4.04 2.28.12s1.76.1 2.64.06 1.66-.24 2.34-.6 1.18-.94 1.5-1.74c.24-.88.26-1.6.06-2.16s-.56-1.02-1.08-1.38-1.14-.6-1.86-.72-1.4-.18-2.04-.18a2020.392 2020.392 0 0 1-31.32-.24l9.84-17.52c1.6-3.12 3.2-6.26 4.8-9.42s3.04-6.42 4.32-9.78c.32-.96.7-2.06 1.14-3.3s.74-2.48.9-3.72.16-2.44 0-3.6-.64-2.22-1.44-3.18-1.82-1.56-3.06-1.8-2.54-.3-3.9-.18-2.7.38-4.02.78-2.46.72-3.42.96c-3.2.88-6.36 1.88-9.48 3s-6.2 2.32-9.24 3.6c-6.48 2.64-12.86 5.46-19.14 8.46s-12.5 6.18-18.66 9.54-12.2 6.92-18.12 10.68-11.52 7.96-16.8 12.6c-1.84 1.6-3.76 3.46-5.76 5.58s-3.68 4.38-5.04 6.78-2.22 4.92-2.58 7.56.22 5.24 1.74 7.8c.56.96 1.28 1.5 2.16 1.62s1.68-.06 2.4-.54 1.22-1.16 1.5-2.04.14-1.8-.42-2.76c-.48-.96-.72-1.96-.72-3s.18-2.06.54-3.06.82-1.98 1.38-2.94 1.16-1.84 1.8-2.64c1.92-2.64 4.1-5.08 6.54-7.32s5.02-4.38 7.74-6.42 5.48-3.94 8.28-5.7 5.6-3.48 8.4-5.16c6.24-3.84 12.62-7.38 19.14-10.62s13.18-6.3 19.98-9.18c3.12-1.36 6.26-2.64 9.42-3.84s6.38-2.36 9.66-3.48c.96-.32 2.04-.72 3.24-1.2s2.46-.92 3.78-1.32 2.64-.72 3.96-.96 2.5-.24 3.54 0c.16 1.36-.12 2.84-.84 4.44s-1.28 2.96-1.68 4.08c-.8 1.92-1.66 3.82-2.58 5.7s-1.82 3.74-2.7 5.58c-1.84 3.52-3.72 7-5.64 10.44s-3.84 6.92-5.76 10.44l-2.88 5.04c-5.04 0-10.02-.02-14.94-.06s-9.86-.02-14.82.06l-9.72.24c-3.2.08-6.4.2-9.6.36-2.32.16-4.72.3-7.2.42s-4.8.58-6.96 1.38c-2 .8-3.06 1.84-3.18 3.12s.24 2.58 1.08 3.9 1.92 2.58 3.24 3.78 2.46 2.12 3.42 2.76c5.76 3.84 11.9 7.26 18.42 10.26s13.14 5.38 19.86 7.14c.96.24 2.16.48 3.6.72zm3.12-6.24c-.8.16-1.7.14-2.7-.06s-2.02-.44-3.06-.72-2.02-.6-2.94-.96-1.66-.62-2.22-.78c-2.56-.88-5.04-1.78-7.44-2.7s-4.8-1.94-7.2-3.06c-2.32-1.12-4.6-2.24-6.84-3.36s-4.44-2.36-6.6-3.72c-.8-.48-1.92-1.12-3.36-1.92s-2.6-1.68-3.48-2.64l5.16-.72c2.88-.32 5.78-.52 8.7-.6l8.82-.24c5.52-.16 11.06-.22 16.62-.18s11.14.1 16.74.18l-4.44 8.16c-1.12 2-2.28 4.14-3.48 6.42s-1.96 4.58-2.28 6.9zm53.34-11.94c1.16.2 2.3.22 3.42.06 3.36-.64 6.58-1.64 9.66-3s6.22-2.6 9.42-3.72c1.36-.48 2.74-.84 4.14-1.08s2.78-.52 4.14-.84c.72-.16 1.38-.48 1.98-.96s1.04-1 1.32-1.56.34-1.16.18-1.8-.64-1.24-1.44-1.8c-1.04-.72-2.36-.92-3.96-.6s-2.92.6-3.96.84c-2.32.56-4.62 1.28-6.9 2.16s-4.54 1.76-6.78 2.64c-1.36.56-2.7 1.1-4.02 1.62s-2.66.94-4.02 1.26c.32-.8.76-1.64 1.32-2.52s1.18-1.74 1.86-2.58 1.32-1.6 1.92-2.28 1.06-1.22 1.38-1.62c1.52-1.92 3.08-3.78 4.68-5.58s3.24-3.58 4.92-5.34c3.12-3.2 6.36-6.26 9.72-9.18s6.88-5.66 10.56-8.22c.64-.48 1.02-1.08 1.14-1.8s.04-1.38-.24-1.98-.72-1.08-1.32-1.44-1.3-.42-2.1-.18c-1.36.32-2.74 1.14-4.14 2.46s-2.66 2.42-3.78 3.3c-3.76 3.04-7.38 6.22-10.86 9.54s-6.86 6.78-10.14 10.38c-.96 1.04-2.28 2.46-3.96 4.26s-3.22 3.74-4.62 5.82-2.42 4.18-3.06 6.3-.4 3.98.72 5.58c.72 1.04 1.66 1.66 2.82 1.86zm34.92.9c2.28 0 4.58-.36 6.9-1.08s4.36-1.78 6.12-3.18 2.72-2.98 2.88-4.74c1.12 0 2.16-.02 3.12-.06s1.72-.06 2.28-.06c2.32 0 4.62-.02 6.9-.06s4.58-.1 6.9-.18c.72 0 1.68.04 2.88.12s2.4.12 3.6.12 2.34-.12 3.42-.36 1.86-.72 2.34-1.44c.96-1.28 1.24-2.26.84-2.94s-1.08-1.2-2.04-1.56-2.02-.58-3.18-.66-2.06-.12-2.7-.12l-12.72.36c-2 0-4 .02-6 .06s-4-.02-6-.18c-.64 0-1.36-.08-2.16-.24s-1.56-.24-2.28-.24-1.36.14-1.92.42-.96.9-1.2 1.86c-.4 1.28-.24 2.26.48 2.94s1.64 1.22 2.76 1.62c-.64.56-1.52 1.04-2.64 1.44-.48.16-1.18.38-2.1.66s-1.86.5-2.82.66-1.86.28-2.7.36-1.42 0-1.74-.24l-.12-.12c.08 0 .36-.44.84-1.32s1-1.88 1.56-3l1.62-3.24c.52-1.04.94-1.76 1.26-2.16 2.72-3.84 5.7-7.4 8.94-10.68s6.62-6.48 10.14-9.6c.4-.4 1.36-1.16 2.88-2.28s2.94-2.34 4.26-3.66 2.24-2.64 2.76-3.96.02-2.34-1.5-3.06c-.72-.32-1.44-.36-2.16-.12s-1.4.62-2.04 1.14-1.26 1.08-1.86 1.68-1.14 1.1-1.62 1.5l-9.12 8.28c-.96.88-2.36 2.16-4.2 3.84s-3.82 3.6-5.94 5.76-4.18 4.46-6.18 6.9-3.58 4.84-4.74 7.2-1.76 4.58-1.8 6.66.82 3.88 2.58 5.4c1.2 1.04 2.94 1.56 5.22 1.56zm64.14-1.68c2.72 0 5.42-.36 8.1-1.08s5.34-1.54 7.98-2.46 5.3-1.8 7.98-2.64 5.38-1.38 8.1-1.62c.8 0 1.48-.24 2.04-.72s.94-1.04 1.14-1.68.22-1.3.06-1.98-.6-1.26-1.32-1.74c-.56-.4-1.2-.62-1.92-.66s-1.46.02-2.22.18-1.52.36-2.28.6-1.42.44-1.98.6c-2.24.56-4.44 1.14-6.6 1.74s-4.36 1.22-6.6 1.86l-5.88 1.8c.32-.56.46-1.16.42-1.8s-.38-1.36-1.02-2.16c-.88-.88-1.94-1.32-3.18-1.32s-2.42.12-3.54.36c-1.28.4-2.64.92-4.08
11.56s-2.9 1.26-4.38 1.86-2.96 1.1-4.44 1.5-2.94.6-4.38.6c.72-.88 1.3-1.76 1.74-2.64s.26-1.88-.54-3-1.96-1.68-3.48-1.68c-1.2.08-2.08.52-2.64 1.32s-.76 1.64-.6 2.52c-.64.96-1.18 1.96-1.62 3s-.62 2.02-.54 2.94.48 1.72 1.2 2.4 1.88 1.14 3.48 1.38c2.56.4 5.22.2 7.98-.6s5.5-1.72 8.22-2.76c0 1.12.48 2.12 1.44 3 .8.88 1.92 1.32 3.36 1.32zm27.18 19.5c1.16.12 2.18-.22 3.06-1.02 1.92-1.84 3.8-3.7 5.64-5.58s3.68-3.74 5.52-5.58c3.04-2.4 6.28-4.58 9.72-6.54s7-3.6 10.68-4.92 7.46-2.3 11.34-2.94 7.74-.88 11.58-.72c.96 0 1.74-.28 2.34-.84s.96-1.24 1.08-2.04 0-1.56-.36-2.28-1.02-1.2-1.98-1.44c-1.2-.32-2.58-.36-4.14-.12s-2.9.44-4.02.6c-3.44.48-6.8 1.22-10.08 2.22s-6.48 2.18-9.6 3.54c.24-.56.36-1.12.36-1.68-.16-1.6-.96-2.62-2.4-3.06s-2.84-.58-4.2-.42c-.56-.72-1.4-1.28-2.52-1.68s-2.32-.66-3.6-.78-2.54-.16-3.78-.12-2.22.1-2.94.18c-2.08.16-4.16.64-6.24 1.44s-3.88 2-5.4 3.6c-.88.88-1.52 1.86-1.92 2.94s-.52 2.12-.36 3.12.58 1.86 1.26 2.58 1.7 1.16 3.06 1.32c1.84.16 3.68-.08 5.52-.72s3.64-1.28 5.4-1.92c1.04-.32 2.4-.88 4.08-1.68-3.04 2.8-5.96 5.74-8.76 8.82s-5.6 6.14-8.4 9.18c-.72.64-1.34 1.3-1.86 1.98s-.66 1.5-.42 2.46c.4 1.28 1.18 1.98 2.34 2.1zm5.94-26.7c.64-.4 1.44-.74 2.4-1.02s1.92-.5 2.88-.66c-1.04.4-2 .74-2.88 1.02s-1.68.5-2.4.66zm72.72 7.2c2.72 0 5.42-.36 8.1-1.08s5.34-1.54 7.98-2.46 5.3-1.8 7.98-2.64 5.38-1.38 8.1-1.62c.8 0 1.48-.24 2.04-.72s.94-1.04 1.14-1.68.22-1.3.06-1.98-.6-1.26-1.32-1.74c-.56-.4-1.2-.62-1.92-.66s-1.46.02-2.22.18-1.52.36-2.28.6-1.42.44-1.98.6c-2.24.56-4.44 1.14-6.6 1.74s-4.36 1.22-6.6 1.86l-5.88 1.8c.32-.56.46-1.16.42-1.8s-.38-1.36-1.02-2.16c-.88-.88-1.94-1.32-3.18-1.32s-2.42.12-3.54.36c-1.28.4-2.64.92-4.08 1.56s-2.9 1.26-4.38 1.86-2.96 1.1-4.44 1.5-2.94.6-4.38.6c.72-.88 1.3-1.76 1.74-2.64s.26-1.88-.54-3-1.96-1.68-3.48-1.68c-1.2.08-2.08.52-2.64 1.32s-.76 1.64-.6 2.52c-.64.96-1.18 1.96-1.62 3s-.62 2.02-.54 2.94.48 1.72 1.2 2.4 1.88 1.14 3.48 1.38c2.56.4 5.22.2 7.98-.6s5.5-1.72 8.22-2.76c0 1.12.48 2.12 1.44 3 .8.88 1.92 1.32 3.36 1.32zm41.1-.12c1.4.16 2.8.2 4.2.12s2.74-.2 4.02-.36c4.88-.48 9.68-1.22 14.4-2.22s9.48-2.06 14.28-3.18c1.84-.4 3.66-.82 5.46-1.26s3.62-.74 5.46-.9c1.36-.08 2.26-.48 2.7-1.2s.54-1.5.3-2.34-.76-1.58-1.56-2.22-1.8-.92-3-.84c-2.8.32-5.58.82-8.34 1.5s-5.54 1.34-8.34 1.98c-3.84.88-7.7 1.72-11.58 2.52s-7.78 1.36-11.7 1.68h-1.74c-.92 0-1.92-.04-3-.12s-2.1-.22-3.06-.42-1.6-.46-1.92-.78c.96.16 2.08.3 3.36.42s2.52.12 3.72 0 2.28-.38 3.24-.78 1.68-1.08 2.16-2.04c.56-1.28.62-2.34.18-3.18s-1.22-1.5-2.34-1.98-2.44-.76-3.96-.84-3.04-.04-4.56.12-2.9.42-4.14.78-2.14.82-2.7 1.38c-.88.8-1.48 1.7-1.8 2.7s-.42 2.02-.3 3.06.44 2.04.96 3 1.22 1.8 2.1 2.52c1.04.88 2.2 1.54 3.48 1.98s2.62.74 4.02.9zm43.86-1.2c1.2 1.2 2.64 1.56 4.32 1.08 1.36-.32 2.56-.94 3.6-1.86s2.04-1.82 3-2.7 1.92-1.82 2.88-2.82 1.88-2.02 2.76-3.06c1.28.88 2.76 1.52 4.44 1.92s3.28.68 4.8.84c2.16.16 4.32.24 6.48.24h6.48c1.28-.08 2.66-.06 4.14.06s2.86.02 4.14-.3c.8 0 1.46-.22 1.98-.66s.9-.98 1.14-1.62.26-1.3.06-1.98-.62-1.26-1.26-1.74-1.4-.78-2.28-.9-1.8-.14-2.76-.06-1.9.18-2.82.3-1.74.18-2.46.18-2 .06-3.84.18-3.78.16-5.82.12-3.9-.2-5.58-.48-2.72-.82-3.12-1.62c0-.96-.16-1.88-.48-2.76s-1.08-1.4-2.28-1.56c-.72-.08-1.32.02-1.8.3s-.9.66-1.26 1.14-.68 1-.96 1.56-.58 1.08-.9 1.56c-1.36 2.24-3.08 4.24-5.16 6 .16-1.2 0-2.24-.48-3.12s-1.52-1.36-3.12-1.44c-1.36 0-2.32.56-2.88 1.68s-.64 2.2-.24 3.24c-.24.64-.5 1.32-.78 2.04s-.52 1.44-.72 2.16-.26 1.42-.18 2.1.4 1.34.96 1.98zm41.82 20.82c1.16.12 2.18-.22 3.06-1.02 1.92-1.84 3.8-3.7 5.64-5.58s3.68-3.74 5.52-5.58c3.04-2.4 6.28-4.58 9.72-6.54s7-3.6 10.68-4.92 7.46-2.3 11.34-2.94 7.74-.88 11.58-.72c.96 0 1.74-.28 2.34-.84s.96-1.24 1.08-2.04 0-1.56-.36-2.28-1.02-1.2-1.98-1.44c-1.2-.32-2.58-.36-4.14-.12s-2.9.44-4.02.6c-3.44.48-6.8 1.22-10.08 2.22s-6.48 2.18-9.6 3.54c.24-.56.36-1.12.36-1.68-.16-1.6-.96-2.62-2.4-3.06s-2.84-.58-4.2-.42c-.56-.72-1.4-1.28-2.52-1.68s-2.32-.66-3.6-.78-2.54-.16-3.78-.12-2.22.1-2.94.18c-2.08.16-4.16.64-6.24 1.44s-3.88 2-5.4 3.6c-.88.88-1.52 1.86-1.92 2.94s-.52 2.12-.36 3.12.58 1.86 1.26 2.58 1.7 1.16 3.06 1.32c1.84.16 3.68-.08 5.52-.72s3.64-1.28 5.4-1.92c1.04-.32 2.4-.88 4.08-1.68-3.04 2.8-5.96 5.74-8.76 8.82s-5.6 6.14-8.4 9.18c-.72.64-1.34 1.3-1.86 1.98s-.66 1.5-.42 2.46c.4 1.28 1.18 1.98 2.34 2.1zm5.94-26.7c.64-.4 1.44-.74 2.4-1.02s1.92-.5 2.88-.66c-1.04.4-2 .74-2.88 1.02s-1.68.5-2.4.66zm72.72 7.2c2.72 0 5.42-.36 8.1-1.08s5.34-1.54 7.98-2.46 5.3-1.8 7.98-2.64 5.38-1.38 8.1-1.62c.8 0 1.48-.24 2.04-.72s.94-1.04 1.14-1.68.22-1.3.06-1.98-.6-1.26-1.32-1.74c-.56-.4-1.2-.62-1.92-.66s-1.46.02-2.22.18-1.52.36-2.28.6-1.42.44-1.98.6c-2.24.56-4.44 1.14-6.6 1.74s-4.36 1.22-6.6 1.86l-5.88 1.8c.32-.56.46-1.16.42-1.8s-.38-1.36-1.02-2.16c-.88-.88-1.94-1.32-3.18-1.32s-2.42.12-3.54.36c-1.28.4-2.64.92-4.08
11.56s-2.9 1.26-4.38 1.86-2.96 1.1-4.44 1.5-2.94.6-4.38.6c.72-.88 1.3-1.76 1.74-2.64s.26-1.88-.54-3-1.96-1.68-3.48-1.68c-1.2.08-2.08.52-2.64 1.32s-.76 1.64-.6 2.52c-.64.96-1.18 1.96-1.62 3s-.62 2.02-.54 2.94.48 1.72 1.2 2.4 1.88 1.14 3.48 1.38c2.56.4 5.22.2 7.98-.6s5.5-1.72 8.22-2.76c0 1.12.48 2.12 1.44 3 .8.88 1.92 1.32 3.36 1.32zm41.1-.12c1.4.16 2.8.2 4.2.12s2.74-.2 4.02-.36c4.88-.48 9.68-1.22 14.4-2.22s9.48-2.06 14.28-3.18c1.84-.4 3.66-.82 5.46-1.26s3.62-.74 5.46-.9c1.36-.08 2.26-.48 2.7-1.2s.54-1.5.3-2.34-.76-1.58-1.56-2.22-1.8-.92-3-.84c-2.8.32-5.58.82-8.34 1.5s-5.54 1.34-8.34 1.98c-3.84.88-7.7 1.72-11.58 2.52s-7.78 1.36-11.7 1.68h-1.74c-.92 0-1.92-.04-3-.12s-2.1-.22-3.06-.42-1.6-.46-1.92-.78c.96.16 2.08.3 3.36.42s2.52.12 3.72 0 2.28-.38 3.24-.78 1.68-1.08 2.16-2.04c.56-1.28.62-2.34.18-3.18s-1.22-1.5-2.34-1.98-2.44-.76-3.96-.84-3.04-.04-4.56.12-2.9.42-4.14.78-2.14.82-2.7 1.38c-.88.8-1.48 1.7-1.8 2.7s-.42 2.02-.3 3.06.44 2.04.96 3 1.22 1.8 2.1 2.52c1.04.88 2.2 1.54 3.48 1.98s2.62.74 4.02.9z" fill="currentColor"></path></svg> © <time>2026</time></p></div></footer></div></div></div>
1<script>requestAnimationFrame(function(){$RT=performance.now()});</script>
1<div hidden id="S:0"><div class="pt-6 pb-4 space-y-2 md:space-y-5"><ul><li class="py-4"><a class="block text-gray-900 no-underline dark:text-gray-100" href="/posts/how-expensive-is-prague"><article data-vt-name="vt-post-row-how-expensive-is-prague" data-vt-class="row"><div class="text-sm font-medium leading-6 text-gray-500 dark:text-gray-400 sm:text-base" data-vt-name="vt-post-date-how-expensive-is-prague" data-vt-class="date"><time dateTime="2024-01-24T00:00:00.000Z">Jan 24, 2024</time></div><h2 class="md:text-3xl text-black dark:text-white space_grotesk_9957aa6b-module__ZewwGG__className my-2 grow text-2xl font-bold leading-8 tracking-tight"><span data-vt-name="vt-post-title-how-expensive-is-prague" data-vt-class="title">How expensive is Prague?</span></h2><div class="prose max-w-none text-gray-500 dark:prose-invert dark:text-gray-400">A Latino perspective on renting, healthcare, groceries, and pretty much everything when it comes to the cost of living in the Czech capital.</div></article></a></li><li class="py-4"><a class="block text-gray-900 no-underline dark:text-gray-100" href="/posts/2022-wrapped"><article data-vt-name="vt-post-row-2022-wrapped" data-vt-class="row"><div class="text-sm font-medium leading-6 text-gray-500 dark:text-gray-400 sm:text-base" data-vt-name="vt-post-date-2022-wrapped" data-vt-class="date"><time dateTime="2022-12-29T00:00:00.000Z">Dec 29, 2022</time></div><h2 class="md:text-3xl text-black dark:text-white space_grotesk_9957aa6b-module__ZewwGG__className my-2 grow text-2xl font-bold leading-8 tracking-tight"><span data-vt-name="vt-post-title-2022-wrapped" data-vt-class="title">2022 Wrapped: Communities, Public Speaking, and Other DevRel Stuff From a Non-DevRel Engineer</span></h2><div class="prose max-w-none text-gray-500 dark:prose-invert dark:text-gray-400">Itâs that epiphany time of the year, again! But, before, a bit of an introduction!</div></article></a></li><li class="py-4"><a class="block text-gray-900 no-underline dark:text-gray-100" href="/posts/jheniffer-was-always-my-favorite-color"><article data-vt-name="vt-post-row-jheniffer-was-always-my-favorite-color" data-vt-class="row"><div class="text-sm font-medium leading-6 text-gray-500 dark:text-gray-400 sm:text-base" data-vt-name="vt-post-date-jheniffer-was-always-my-favorite-color" data-vt-class="date"><time dateTime="2020-08-20T00:00:00.000Z">Aug 20, 2020</time></div><h2 class="md:text-3xl text-black dark:text-white space_grotesk_9957aa6b-module__ZewwGG__className my-2 grow text-2xl font-bold leading-8 tracking-tight"><span data-vt-name="vt-post-title-jheniffer-was-always-my-favorite-color" data-vt-class="title">Jheniffer was always my favorite color</span></h2><div class="prose max-w-none text-gray-500 dark:prose-invert dark:text-gray-400">I hope yall don't mind the inconvenience, but I need to talk about Jheniffer Rodrigues.</div></article></a></li><li class="py-4"><a class="block text-gray-900 no-underline dark:text-gray-100" href="/posts/driving-towards-a-universal-navigation-strategy-in-react"><article data-vt-name="vt-post-row-driving-towards-a-universal-navigation-strategy-in-react" data-vt-class="row"><div class="text-sm font-medium leading-6 text-gray-500 dark:text-gray-400 sm:text-base" data-vt-name="vt-post-date-driving-towards-a-universal-navigation-strategy-in-react" data-vt-class="date"><time dateTime="2020-01-13T00:00:00.000Z">Jan 13, 2020</time></div><h2 class="md:text-3xl text-black dark:text-white space_grotesk_9957aa6b-module__ZewwGG__className my-2 grow text-2xl font-bold leading-8 tracking-tight"><span data-vt-name="vt-post-title-driving-towards-a-universal-navigation-strategy-in-react" data-vt-class="title">Driving towards a universal navigation strategy in React</span></h2><div class="prose max-w-none text-gray-500 dark:prose-invert dark:text-gray-400">When I joined STRV, they had a specific request for me; to build a front-end app for iOS, Android, and Web, sharing component and business logic amongst all the platforms.</div></article></a></li><li class="py-4"><a class="block text-gray-900 no-underline dark:text-gray-100" href="/posts/it-s-all-about-trusting-the-magic-of-beginnings"><article data-vt-name="vt-post-row-it-s-all-about-trusting-the-magic-of-beginnings" data-vt-class="row"><div class="text-sm font-medium leading-6 text-gray-500 dark:text-gray-400 sm:text-base" data-vt-name="vt-post-date-it-s-all-about-trusting-the-magic-of-beginnings" data-vt-class="date"><time dateTime="2019-07-15T00:00:00.000Z">Jul 15, 2019</time></div><h2 class="md:text-3xl text-black dark:text-white space_grotesk_9957aa6b-module__ZewwGG__className my-2 grow text-2xl font-bold leading-8 tracking-tight"><span data-vt-name="vt-post-title-it-s-all-about-trusting-the-magic-of-beginnings" data-vt-class="title">It's all about trusting the magic of beginnings</span></h2><div class="prose max-w-none text-gray-500 dark:prose-invert dark:text-gray-400">After almost two years immersed in countless exciting challenges, it's time to move on.</div></article></a></li><li class="py-4"><a class="block text-gray-900 no-underline dark:text-gray-100" href="/posts/a-whole-day-playing-with-ipfs"><article data-vt-name="vt-post-row-a-whole-day-playing-with-ipfs" data-vt-class="row"><div class="text-sm font-medium leading-6 text-gray-500 dark:text-gray-400 sm:text-base" data-vt-name="vt-post-date-a-whole-day-playing-with-ipfs" data-vt-class="date"><time dateTime="2017-12-15T00:00:00.000Z">Dec 15, 2017</time></div><h2 class="md:text-3xl text-black dark:text-white space_grotesk_9957aa6b-module__ZewwGG__className my-2 grow text-2xl font-bold leading-8 tracking-tight"><span data-vt-name="vt-post-title-a-whole-day-playing-with-ipfs" data-vt-class="title">A Whole Day Playing with IPFS</span></h2><div class="prose max-w-none text-gray-500 dark:prose-invert dark:text-gray-400">This is mostly a controversial decentralized web technologies research story but, before starting, there are a few things I'd like to ensure you all, my beloved readers, are aware of.</div></article></a></li><li class="py-4"><a class="block text-gray-900 no-underline dark:text-gray-100" href="/posts/swift-in-the-sky-with-types"><article data-vt-name="vt-post-row-swift-in-the-sky-with-types" data-vt-class="row"><div class="text-sm font-medium leading-6 text-gray-500 dark:text-gray-400 sm:text-base" data-vt-name="vt-post-date-swift-in-the-sky-with-types" data-vt-class="date"><time dateTime="2016-03-28T00:00:00.000Z">Mar 28, 2016</time></div><h2 class="md:text-3xl text-black dark:text-white space_grotesk_9957aa6b-module__ZewwGG__className my-2 grow text-2xl font-bold leading-8 tracking-tight"><span data-vt-name="vt-post-title-swift-in-the-sky-with-types" data-vt-class="title">ð§ð· â Swift In The Sky With Types</span></h2><div class="prose max-w-none text-gray-500 dark:prose-invert dark:text-gray-400">... Ou apenas mais uma conversa sobre linguagens, compiladores, tipos e... Swift!</div></article></a></li><li class="py-4"><a class="block text-gray-900 no-underline dark:text-gray-100" href="/posts/o-que-ha-de-novo-com-o-angularjs"><article data-vt-name="vt-post-row-o-que-ha-de-novo-com-o-angularjs" data-vt-class="row"><div class="text-sm font-medium leading-6 text-gray-500 dark:text-gray-400 sm:text-base" data-vt-name="vt-post-date-o-que-ha-de-novo-com-o-angularjs" data-vt-class="date"><time dateTime="2014-11-10T00:00:00.000Z">Nov 10, 2014</time></div><h2 class="md:text-3xl text-black dark:text-white space_grotesk_9957aa6b-module__ZewwGG__className my-2 grow text-2xl font-bold leading-8 tracking-tight"><span data-vt-name="vt-post-title-o-que-ha-de-novo-com-o-angularjs" data-vt-class="title">ð§ð· â O que há de novo com o AngularJS?</span></h2><div class="prose max-w-none text-gray-500 dark:prose-invert dark:text-gray-400">Mudanças anunciadas na ng-Europe, a versão 1.3, âmorteâ de APIs⦠O AngularJS 2.0 ainda será o AngularJS que conhecemos?</div></article></a></li></ul></div></div>
1<script>$RB=[];$RV=function(a){$RT=performance.now();for(var b=0;b<a.length;b+=2){var c=a[b],e=a[b+1];null!==e.parentNode&&e.parentNode.removeChild(e);var f=c.parentNode;if(f){var g=c.previousSibling,h=0;do{if(c&&8===c.nodeType){var d=c.data;if("/$"===d||"/&"===d)if(0===h)break;else h--;else"$"!==d&&"$?"!==d&&"$~"!==d&&"$!"!==d&&"&"!==d||h++}d=c.nextSibling;f.removeChild(c);c=d}while(c);for(;e.firstChild;)f.insertBefore(e.firstChild,c);g.data="$";g._reactRetry&&requestAnimationFrame(g._reactRetry)}}a.length=0}; 2$RC=function(a,b){if(b=document.getElementById(b))(a=document.getElementById(a))?(a.previousSibling.data="$~",$RB.push(a,b),2===$RB.length&&("number"!==typeof $RT?requestAnimationFrame($RV.bind(null,$RB)):(a=performance.now(),setTimeout($RV.bind(null,$RB),2300>a&&2E3<a?2300-a:$RT+300-a)))):b.parentNode.removeChild(b)};$RC("B:0","S:0")</script>
2<script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"allPosts":[{"title":"How expensive is Prague?","date":"2024-01-24T00:00:00.000Z","summary":"A Latino perspective on renting, healthcare, groceries, and pretty much everything when it comes to the cost of living in the Czech capital.","language":"en","tags":["career","life"],"slug":"how-expensive-is-prague","hero":"/content/posts/how-expensive-is-prague/hero.png","readingTime":{"text":"12 min read","minutes":11.03,"time":661800,"words":2206},"body":{"code":"const{Fragment:e,jsx:n,jsxs:a}=arguments[0];function _createMdxContent(i){const t={a:\"a\",code:\"code\",em:\"em\",h3:\"h3\",h4:\"h4\",li:\"li\",ol:\"ol\",p:\"p\",span:\"span\",strong:\"strong\",ul:\"ul\",...i.components},{Admonition:r,Price:o,Tweet:h}=t;return r||_missingMdxReference(\"Admonition\",!1),r.Box||_missingMdxReference(\"Admonition.Box\",!0),r.Description||_missingMdxReference(\"Admonition.Description\",!0),r.Title||_missingMdxReference(\"Admonition.Title\",!0),o||_missingMdxReference(\"Price\",!0),h||_missingMdxReference(\"Tweet\",!0),a(e,{children:[a(t.h3,{id:\"preamble\",children:[n(t.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#preamble\",children:n(t.span,{className:\"icon icon-link\"})}),\"Preamble\"]}),\"\\n\",n(t.p,{children:\"There's a recent trend amongst expat Brazilian developers on X, formerly\\nTwitter, where they share their cost of living in the places they're now based.\"}),\"\\n\",a(t.p,{children:[\"I first heard of this through a fellow Google Developer Expert, Lucas Santos,\\nwho shared a little about\\n\",n(t.a,{href:\"https://twitter.com/_StaticVoid/status/1743682350909690199\",children:\"his life in Stockholm, Sweden\"}),\".\"]}),\"\\n\",a(t.p,{children:[\"He was replying to Alekson's super\\n\",n(t.a,{href:\"https://twitter.com/Alekson/status/1743310755900858805\",children:\"informative post\"}),\" that\\ncovered how expensive Montreal, Canada, is nowadays. Alekson, on his turn, was\\nreplying to Augusto's take on the\\n\",n(t.a,{href:\"https://twitter.com/RealGalego/status/1743236322486039009\",children:\"cost of living in northern Italy\"}),\".\"]}),\"\\n\",n(t.p,{children:\"I then decided to jump on that too:\"}),\"\\n\",n(h,{id:\"1744324760119435446\"}),\"\\n\",n(t.p,{children:\"Mostly because:\"}),\"\\n\",a(t.ul,{children:[\"\\n\",n(t.li,{children:\"I think this kind of content is super valid for those who want to live abroad.\\nEspecially those coming from quite different realities, like LATAM, APAC, and\\nothers.\"}),\"\\n\",n(t.li,{children:\"There is a lot of misinformation about the cost of living as an expat spread\\nthrough Instagram Reels and TikTok out there that try hard to romanticize life\\nabroad at any cost.\"}),\"\\n\",n(t.li,{children:\"I wish I had something similar before I moved here and, even though I had\\nproperly planned moving here, I ended up being surprised by the overall costs\\nand how much my purchasing power dropped for a while after moving.\"}),\"\\n\"]}),\"\\n\",n(t.p,{children:\"Given that the original thread in Portuguese had considerable engagement, with a\\nfew questions and some people bookmarking it, I decided to turn it into a blog\\npost in English, so that it'd reach a broader audience and also be properly\\nindexed and made more discoverable.\"}),\"\\n\",n(t.p,{children:\"Before we start, just a little bit of context:\"}),\"\\n\",a(t.ol,{children:[\"\\n\",n(t.li,{children:\"I was born and raised in Fortaleza, Brazil. I was remotely working at a\\nUS-based company before moving to Prague.\"}),\"\\n\",n(t.li,{children:\"I moved with my wife. Nowadays we have Ricardo, our dog.\"}),\"\\n\",n(t.li,{children:\"I am not an EU citizen and I run under a work permit here.\"}),\"\\n\"]}),\"\\n\",n(t.p,{children:\"Here we go: my cost of living in Prague, Czech Republic.\"}),\"\\n\",a(r.Box,{severity:\"warning\",children:[n(r.Title,{children:\"Heads-up!\"}),a(r.Description,{children:[n(t.p,{children:\"Sometimes it's harder to reason about costs when you're coming from a currency\\nwith a whole other order of magnitude. That was a challenge for me coming from\\nBRL to CZK.\"}),n(t.p,{children:\"As a matter of fact, it was one of the biggest feedback others and I got when\\nfirst sharing this kind of post over Twitter.\"}),a(t.p,{children:[\"For that, I am making this post (originally written in \",n(t.code,{children:\"CZK\"}),\") also available in\\nthe following currencies: \",n(t.a,{href:\"?currency=USD\",children:\"USD\"}),\", \",n(t.a,{href:\"?currency=EUR\",children:\"EUR\"}),\",\\n\",n(t.a,{href:\"?currency=GBP\",children:\"GBP\"}),\", \",n(t.a,{href:\"?currency=BRL\",children:\"BRL\"}),\", \",n(t.a,{href:\"?currency=JPY\",children:\"JPY\"}),\",\\n\",n(t.a,{href:\"?currency=AUD\",children:\"AUD\"}),\", \",n(t.a,{href:\"?currency=AUD\",children:\"AUD\"}),\", \",n(t.a,{href:\"?currency=AUD\",children:\"CAD\"}),\",\\n\",n(t.a,{href:\"?currency=CHF\",children:\"CHF\"}),\", and \",n(t.a,{href:\"?currency=INR\",children:\"INR\"}),\".\"]}),n(t.p,{children:\"Please note that conversion rates are fetched in build time and might be\\noutdated.\"})]})]}),\"\\n\",a(t.h3,{id:\"-renting\",children:[n(t.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#-renting\",children:n(t.span,{className:\"icon icon-link\"})}),n(t.span,{role:\"img\",\"aria-label\":\"house\",children:\"ð \"}),\" Renting\"]}),\"\\n\",a(t.p,{children:[\"Renting a flat in the center of Pragueâas well as almost any European\\ncapitalâwill sound insanely expensive for anyone coming from pretty much any\\ncity in Latin America and, in my opinion, one just can't compare the baseline\\nhere. Just like several other expats, when I arrived my company\\n(\",n(t.a,{href:\"https://www.strv.com\",children:\"STRV\"}),\") arranged a short-term flat for 30 days. This flat\\nwas around 50m², the layout was what they call \",n(t.code,{children:\"2 + kk\"}),\" (explanation below) and\\nit was located in\\n\",n(t.a,{href:\"https://cs.wikipedia.org/wiki/Invali
2dovna_(Praha)\",children:\"Invalidovna, Prague 8\"}),\".\"]}),\"\\n\",n(t.p,{children:\"The building in particular (and the neighborhood as a whole) had several pros:\"}),\"\\n\",a(t.ul,{children:[\"\\n\",n(t.li,{children:\"Close to a metro station and a cable car/bus stop;\"}),\"\\n\",n(t.li,{children:\"Close to Karlin, the district where my company's office and several others\\nwere located (kind of like one of the tech hubs here in Prague);\"}),\"\\n\",n(t.li,{children:\"Pubs and cafés all around;\"}),\"\\n\",n(t.li,{children:\"The building itself was mostly inhabited by expats and thus the staff spoke\\nEnglish, which made life a lot easier.\"}),\"\\n\"]}),\"\\n\",n(t.p,{children:\"We decided to stay in this building/district. After 30 days, we managed to move\\ninto a studio (~30m²) in the same building while we waited for a larger\\napartment to be vacant (the same as the one the company had picked up for me).\"}),\"\\n\",a(t.p,{children:[\"After about four/five months, we got that one for \",n(o,{amount:23700}),\"/month,\\nwhich included internet (\",n(o,{amount:300}
2),\") and all utilities for two\\npeople (\",n(o,{amount:3e3}),\").\"]}),\"\\n\",n(t.p,{children:\"The pandemic came and we realized the two of us could use some more space in an\\napartment. That was also when Ricardo joined our family and we had to find\\nanother apartment because that one had internal rules against pets.\"}),\"\\n\",a(t.p,{children:[\"In mid-2020, we found ourselves in Prague 10, this time in a very residential\\narea (VrÅ¡ovice), in a 95m² flat and paying \",n(o,{amount:25e3}),\"/month\\n(utilities included). The price per Sqm was way lower than the previous one,\\nmostly because:\"]}),\"\\n\",a(t.ul,{children:[\"\\n\",n(t.li,{children:\"it was a more remote neighborhood,\"}),\"\\n\",n(t.li,{children:\"it had no subway stations nearby, and\"}),\"\\n\",n(t.li,{children:\"the building style was from the Czechoslovak era.\"}),\"\\n\"]}),\"\\n\",n(t.p,{children:\"At the end of 2021, the owner of that apartment passed away and his family\\npresented us with a leave notice.\"}),\"\\n\",a(t.p,{children:[\"And we moved again! This time, we headed to Prague 2\\n(\",n(t.a,{href:\"https://en.wikipedia.org/wiki/New_Town,_Prague\",children:\"Nové MÄsto\"}),\"), to a central\\nquarter and got a 90m² flat.\"]}),\"\\n\",a(t.p,{children:[\"We started at \",n(o,{amount:26500,leading:!0}),\" + utilities and in November 2023\\nwe had our first adjustment. We're now settled at \",n(o,{amount:30750}),\".\"]}),\"\\n\",n(t.p,{children:\"To recap, our experience so far has been:\"}),\"\\n\",a(t.h4,{id:\"2019-20-prague-8\",children:[n(t.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#2019-20-prague-8\",children:n(t.span,{className:\"icon icon-link\"})}),\"2019-20 (Prague 8):\"]}),\"\\n\",a(t.ul,{children:[\"\\n\",n(t.li,{children:\"Modern construction (late 2000s);\"}),\"\\n\",n(t.li,{children:\"Tech bubble area.\"}),\"\\n\"]}),\"\\n\",a(r.Box,{children:[n(r.Title,{children:\"History\"}),n(r.Description,{children:a(t.p,{children:[\"As a matter of fact, the \",n(t.a,{href:\"https://praguemorning.cz/20-years-after-the-floods-karlin-undergone-transformation-and-further-development-awaits\",children:\"great\\nflooding\"}),\"\\nthat hit Prague in August 2002âwhen certain areas of the Czech capital were\\nalmost completely submerged and various historic monuments damagedâ,\\naffected in particular the district of KarlÃn.\"]})})]}),\"\\n\",a(t.h4,{id:\"2020-21-prague-10\",children:[n(t.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#2020-21-prague-10\",children:n(t.span,{className:\"icon icon-link\"})}),\"2020-21 (Prague 10):\"]}),\"\\n\",a(t.ul,{children:[\"\\n\",a(t.li,{children:[n(t.a,{href:\"https://en.wikipedia.org/wiki/Panel%C3%A1k\",children:\"Czechoslovak-era housing estate\"}),\"\\nbuilding;\"]}),\"\\n\",n(t.li,{children:\"Brand new refurbished flat;\"}),\"\\n\",n(t.li,{children:\"Residential neighborhood.\"}),\"\\n\"]}),\"\\n\",a(t.h4,{id:\"2022-now-prague-2\",children:[n(t.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#2022-now-prague-2\",children:n(t.span,{className:\"icon icon-link\"})}),\"2022-Now (Prague 2):\"]}),\"\\n\",a(t.ul,{children:[\"\\n\",a(t.li,{children:[n(t.a,{href:\"https://en.wikipedia.org/wiki/Rondocubism\",children:\"Post-WWI cubism\"}),\" building;\"]}),\"\\n\",n(t.li,{children:\"Brand new refurbished flat;\"}),\"\\n\",n(t.li,{children:\"Kind of part of the historic center of modern Prague.\"}),\"\\n\"]}),\"\\n\",n(t.p,{children:\"If I had to summarize some key points to keep in mind when considering renting a\\nflat in Prague, I'd say:\"}),\"\\n\",a(t.ul,{children:[\"\\n\",a(t.li,{children:[\"The apartment layout model (\",n(t.code,{children:\"2+kk\"}),\", \",n(t.code,{children:\"3+1\"}),\", \",n(t.code,{children:\"4+kk\"}),\", \",n(t.code,{children:\"4+1\"}),\", etc.) and the\\n\",n(t.a,{href:\"https://www.flatio.com/blog/1-kk-2-1-how-to-understand-czech-real-estate-terminology\",children:\"real estate terminology\"}),\"\\nhere.\"]}),\"\\n\",a(t.li,{children:[\"The correlation between the\\n\",n(t.a,{href:\"https://www.valuo.cz/ceny-bytu-na-metru\",children:\"distribution of metro stations and the price per square meter\"}),\".\\nThis probably applies to several other capitals here in Europe.\"]}),\"\\n\",a(t.li,{children:[\"The fact that, in general, renting is more expensive than buying a home due to\\nmortgage rates being cheaper. A\\n\",n(t.a,{href:\"https://www.asociacenajemnihobydleni.cz/aktuality/najemni-bydleni-zustava-nadale-ekonomicky-vyhodnejsi-nez-vlastnicke\",children:\"study\"}),\"\\npublished in January 2024 by the \",n(t.em,{children:\"Rental Housing Association\"}),\" (ANB) has found\\nthat the average monthly mortgage payment for a 53-square-meter-
2apartment is\\nhalf the cost of average monthly rent in Czechia. By the way, I'd say things\\nare like that in much of Europe too!\"]}),\"\\n\",n(t.li,{children:\"The importance of having some cash flow to afford a one/two months deposit and\\npossibly a real estate commission too. This can vary for the better (e.g. no\\ncommission, if you rent directly from the owner) or for the worse (e.g.\\ncommission plus a three-month deposit). In other cities/countries here the\\nreality is worse.\"}),\"\\n\"]}),\"\\n\",a(t.h3,{id:\"-utilities\",children:[n(t.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#-utilities\",children:n(t.span,{className:\"icon icon-link\"})}),n(t.span,{role:\"img\",\"aria-label\":\"\",\"aria-hidden\":!0,children:\"â¡\"}),\" Utilities\"]}),\"\\n\",n(t.p,{children:\"I've seen very different setups when it comes to this.\"}),\"\\n\",a(t.p,{children:[\"There are some arrangements where heating, water, and electricity are included\\nin the rent. In my current apartment, water is included in my monthly rent. I\\nalso pay a fixed monthly deposit of \",n(o,{amount:1500,leading:!0}),\" for\\nelectricity. Last but not least, there's a variable quarterly deposit for\\nheating. I've seen it ranging from \",n(o,{amount:2590,leading:!0}),\" to\"]}),\"\\n\",a(t.p,{children:[n(o,{amount:4840}),\".\"]}),\"\\n\",n(t.p,{children:\"Overall, the calculation here is annual, based on average usage: if you used\\nmore, you pay the difference, if you used less, you get your money back.\"}),\"\\n\",a(t.h3,{id:\"-connectivity\",children:[n(t.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#-connectivity\",children:n(t.span,{className:\"icon icon-link\"})}),\"ð Connectivity\"]}),\"\\n\",a(t.p,{children:[\"I'd say that the internet here is relatively cheap if compared to Brazil. I have\\na \",n(t.code,{children:\"250mb\"}),\" plan from Vodafone for \",n(o,{amount:700}),\" /month. I've also had\\noptical fiber internet for similar rates but unfortunately, this setup isn't\\navailable in my current area. I did notice that neighborhoods within (or nearby)\\nthe historic center share the same issue around fiber internet coverage. I've\\nalso had plans from T-Mobile and O2 for similar rates.\"]}),\"\\n\",a(t.p,{children:[\"In addition, I also have a 5G-based redundancy (unlimited data) for home\\ninternet that costs \",n(o,{amount:900}),\" /month. This is quite useful when my\\nmain network drops during a meeting, for example.\"]}),\"\\n\",n(t.p,{children:\"For cell phones, my wife and I have T-Mobile plans that go around\"}),\"\\n\",a(t.p,{children:[n(o,{amount:1100,leading:!0}),\" each and provide unlimited data/calls here and an\\nadditional \",n(t.code,{children:\"36GB\"}),\" + \",n(t.code,{children:\"100 mins\"}),\" within the EU.\"]}),\"\\n\",a(t.h3,{id:\"-transport\",children:[n(t.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#-transport\",children:n(t.span,{className:\"icon icon-link\"})}),n(t.span,{role:\"img\",\"aria-label\":\"tram car\",children:\"ð\"}),\" Transport\"]}),\"\\n\",a(t.p,{children:[\"Public transport here is insanely efficient. The Prague network is generally one\\nof the highest-ranked in Europe. It's simply well-covered, cheap, and easy to\\nnavigate. \",n(t.a,{href:\"https://pidlitacka.cz/en/pricing\",children:\"Rates\"}),\" are split into short-term\\nand season tickets.\"]}),\"\\n\",a(t.p,{children:[\"It costs me \",n(o,{amount:3650,leading:!0}),\" for unlimited riding the entire\\nnetwork (buses, cable cars, metro lines, boats, city trains, the funicular,\\netc.) within Prague for \",n(t.em,{children:\"a whole year\"}),\".\"]}),\"\\n\",n(t.p,{children:\"By the way, it also happens that some companies include an annual pass as part\\nof their benefits package.\"}),\"\\n\",n(t.p,{children:\"I have never checked the prices of bicycles, electric bikes, and scooters, but\\nI've rented them a few times via apps here and it's quite affordable.\"}),\"\\n\",n(t.p,{children:\"I don't have much idea about the costs of a car either, but I have a few friends\\nwho own one and it seems much more affordable than in Brazil. I have to say that\\nmost of them have small children and/or like to hit the road for the weekend to\\nvisit some country nearby.\"}),\"\\n\",a(t.h3,{id:\"-health-care\",children:[n(t.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#-health-care\",children:n(t.span,{className:\"icon icon-link\"})}),n(t.span,{role:\"img\",\"aria-label\":\"\",\"aria-hidden\":!0,children:\"ð©º\"}),\" Health Care\"]}),\"\\n\",a(t.p,{children:[\"In general, the public health system (\",n(t.a,{href:\"https://www.vzp.cz\",children:\"VZP\"}),\") has your back\\nif you're either a Czech/EU citizen or if you're formally under an employment\\ncontract here, which is my case.\"]}),\"\\n\",a(t.p,{children:[\"Unlike some other EU countries, spouses are not coveredâwhich was a negative\\nsurprise. My wife, for example, had to pay for a private system\\n(\",n(t.a,{href:\"https://www.pvzp.cz\",children:\"PVZP\"}),\") for a long time. A good plan goes around\"]}),\"\\n\",a(t.p,{children:[n(o,{amount:3e3}),\" /month.\"]}),\"\\n\",n(t.p,{children:\"You'll mostly be fine with VZP/PVZP, but there are also some private healthcare\\nclinics for those looking for more comfort/convenienceâand that includes, for\\nexample, being assisted by doctors who speak English.\"}),\"\\n\",a(t.p,{children:[\"We lived our first few years here without it but nowadays this is key to me.\\nMany companies include this in the bonus package. A monthly subscription in\\n\",n(t.a,{href:\"https://www.canadian.cz/en/membership\",children:\"Canadian Medical\"}),\" goes around\"]}),\"\\n\",a(t.p,{children:[n(o,{amount:2990}),\".\"]}),\"\\n\",a(t.h3,{id:\"-pets\",children:[n(t.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#-pets\",children:n(t.span,{className:\"icon icon-link\"})}),n(t.span,{role:\"img\",\"aria-label\":\"dog face\",children:\"ð¶\"}),\" Pets\"]}),\"\\n\",n(t.p,{children:\"For those into pet parenting, I'd it's quite ok too.\"}),\"\\n\",a(t.p,{children:[\"We spend around \",n(o,{amount:1300,leading:!0}),\" on a 6kg dog food package every\\nthree months.\"]}),\"\\n\",a(t.p,{children:[\"We pay for a health plan that costs \",n(o,{amount:810}),\"/month. The plan pays\\nfor itself soon enough, especially in cases of hospital admissions, expensive\\nexams/sampling, etc. One-off vaccines cost in the range of\"]}),\"\\n\",a(t.p,{children:[n(o,{amount:800,leading:!0}),\" - \",n(o,{amount:1200}),\".\"]}),\"\\n\",n(t.p,{children:\"A two-hour visit to a fancy pet shop, with everything included, c
2osts around\"}),\"\\n\",a(t.p,{children:[n(o,{amount:1e3}),\".\"]}),\"\\n\",a(t.h3,{id:\"-going-out\",children:[n(t.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#-going-out\",children:n(t.span,{className:\"icon icon-link\"})}),n(t.span,{role:\"img\",\"aria-label\":\"clinking beer mugs\",children:\"ð»\"}),\" Going Out\"]}),\"\\n\",n(t.p,{children:\"This does vary a lot, but in general, I'd say it's way cheaper than most\\nwestern/northern European capitals and more expensive than cities further east.\"}),\"\\n\",a(t.p,{children:[\"A cappuccino at a fancy café ranges between \",n(o,{amount:75,leading:!0}),\" -\"]}),\"\\n\",a(t.p,{children:[n(o,{amount:95}),\". A whole brunch at a similar place should be around\\n\",n(o,{amount:250}),\".\"]}),\"\\n\",a(t.p,{children:[\"A pint of craft beer in a good bar costs around \",n(o,{amount:70}),\". For about\"]}),\"\\n\",a(t.p,{children:[n(o,{amount:400}),\" you can drink a lot and really good quality beer.\"]}),\"\\n\",a(t.p,{children:[\"Food costs are also within a huge range, but I'd say grabbing lunch costs at\\nleast \",n(o,{amount:180}),\". About \",n(o,{amount:280,leading:!0}),\" will get you\\nlunch at a decent restaurant. Dinner at a fancy place goes around\"]}),\"\\n\",a(t.p,{children:[n(o,{amount:450,leading:!0}),\" - \",n(o,{amount:500,leading:!0}),\" per personâand you'll\\neat well!\"]}),\"\\n\",a(t.h3,{id:\"-groceries\",children:[n(t.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#-groceries\",children:n(t.span,{className:\"icon icon-link\"})}),n(t.span,{role:\"img\",\"aria-label\":\"shopping cart\",children:\"ð\"}),\" Groceries\"]}),\"\\n\",n(t.p,{children:\"This is probably the most variable part of the equation because it takes\\ncountless factors into account.\"}),\"\\n\",n(t.p,{children:\"My wife and I usually make a one-shot order in the range of\"}),\"\\n\",a(t.p,{children:[n(o,{amount:4e3,leading:!0}),\" at the beginning of every month and then we buy other\\nitems on demand. Much of this can be covered with a company meal voucher (usually\\nat \",n(o,{amount:3e3}),\"\\n/month).\"]}),\"\\n\",n(t.p,{children:\"At the end of the month, groceries usually go around\"}),\"\\n\",a(t.p,{children:[n(o,{amount:8e3,leading:!0}),\" - \",n(o,{amount:9e3,leading:!0}),\" for the two of\\nus.\"]}),\"\\n\",a(t.p,{children:[\"If you're wondering about prices for specific items, you might wanna check the\\nEnglish version of \",n(t.a,{href:\"https://www.rohlik.cz/en-CZ\",children:\"Rohlik.cz\"}),\", a fine Czech online\\ngrocery store.\"]}),\"\\n\",a(t.h3,{id:\"-salary-ranges\",children:[n(t.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#-salary-ranges\",children:n(t.span,{className:\"icon icon-link\"})}),n(t.span,{role:\"img\",\"aria-label\":\"money bag\",children:\"ð°\"}),\" Salary Ranges\"]}),\"\\n\",n(t.p,{children:\"I won't disclose my salary here but from what I've noticed in the local market,\\nI'd say that the average salary for a senior engineering position here is\"}),\"\\n\",a(t.p,{children:[n(o,{amount:13e4,leading:!0}),\" - \",n(o,{amount:15e4}),\" /month.\"]}),\"\\n\",a(t.p,{children:[\"People in tech positions are considered highly skilled workers and these numbers\\ndo not reflect the reality of most people here. In fact, looking at some\\n\",n(t.a,{href:\"https://czso.cz/csu/czso/ari/average-wages-2-quarter-of-2023\",children:\"recent data from the statistics office\"}),\",\\nthe average gross monthly salary in Czechia is around \",n(o,{amount:43193}),\".\"]}),\"\\n\",a(t.p,{children:[\"Taxes are based on how much you earn. There are\\n\",n(t.a,{href:\"https://www.platy.cz/en/calculator\",children:\"great tools\"}),\" out there to help you estimate\\nyour net salary.\"]}),\"\\n\",a(t.h3,{id:\"wrapping-up\",children:[n(t.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#wrapping-up\",children:n(t.span,{className:\"icon icon-link\"})}),\"Wrapping Up...\"]}),\"\\n\",a(t.p,{children:[\"At the end of the month, if we filter out fun and entertainment expensesâe.g.\\neating out, cinema and concerts, traveling, etc.âand also investments and\\nsavings, we have a cost baseline of around \",n(o,{amount:55e3}),\".\"]}),\"\\n\",a(t.p,{children:[\"To be honest, I'm not quite sure if I managed to cover everyone's questions\\nabout the costs of living here, \",n(t.strong,{children:\"but\"}),\" I'm always open to anyone who's got\\nquestions about a career as a software engineer and life as an expat.\"]}),\"\\n\",n(t.p,{children:\"Last but not least, this is an ever-living post and I'll keep updating it as I\\nget more feedback and/
2or updates to share.\"})]})}return{default:function(e={}){const{wrapper:a}=e.components||{};return a?n(a,{...e,children:n(_createMdxContent,{...e})}):_createMdxContent(e)}};function _missingMdxReference(e,n){throw new Error(\"Expected \"+(n?\"component\":\"object\")+\" `\"+e+\"` to be defined: you likely forgot to import, pass, or provide it.\")}"},"_tags":["career","life"]},{"title":"2022 Wrapped: Communities, Public Speaking, and Other DevRel Stuff From a Non-DevRel Engineer","date":"2022-12-29T00:00:00.000Z","summary":"Itâs that epiphany time of the year, again! But, before, a bit of an introduction!","language":"en","tags":["career","community","devrel"],"slug":"2022-wrapped","hero":"/content/posts/2022-wrapped/hero.png","readingTime":{"text":"17 min read","minutes":16.69,"time":1001400,"words":3338},"body":{"code":"const{Fragment:e,jsx:n,jsxs:t}=arguments[0];function _createMdxContent(i){const a={a:\"a\",em:\"em\",h2:\"h2\",h3:\"h3\",h4:\"h4\",h5:\"h5\",img:\"img\",li:\"li\",ol:\"ol\",p:\"p\",span:\"span\",strong:\"strong\",ul:\"ul\",...i.components};return t(e,{children:[n(a.p,{children:\"Itâs that epiphany time of the year, again! But, before, a bit of an\\nintroduction!\"}),\"\\n\",n(a.p,{children:\"My passion for developer communities started back in 2014-15 when I first\\nexperienced in my hometown (Fortaleza, Brazil) tons of developers meeting in\\ntheir off hours to discuss their hot takes in the front-end realm back\\nthenâHTML5, canvas, Three.js experiments, CoffeeScript, Web Components, Ionic,\\nand Angular to name a fewâ, challenges theyâve encountered, and different ways\\nof doing things.\"}),\"\\n\",n(a.p,{children:\"This passion only grew over time, but all of these were hit hard by the\\npandemicsâjust like the entire rest of the world, unfortunately.\"}),\"\\n\",n(a.p,{children:\"I don't know you, but, especially in 2022, I feel all about celebrating the\\nendless ways that thousands of front-end/back-end engineers, UI/UX folks, and\\noverall creators of the web, connected in meetups and conferences throughout the\\nwhole year.\"}),\"\\n\",t(a.h2,{id:\"what-you-can-expect-here\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#what-you-can-expect-here\",children:n(a.span,{className:\"icon icon-link\"})}),\"What You Can Expect Here\"]}),\"\\n\",n(a.p,{children:n(a.em,{children:\"TLDR: Matheus' very own Hitchhiker's Guide to the Front-End Conferences, 2023\\nedition.\"})}),\"\\n\",n(a.p,{children:\"Iâve managed to present a few talks that I think went well, and I decided to\\nshare what's worked for me in my process of preparing a tech session.\"}),\"\\n\",n(a.p,{children:\"Furthermore, throughout this yearâin late 2021, to be honestâ, I started running\\na new personal set of practices for organizing my participation in developer\\nconferencesâsomething I found to be even trickier if your official job position\\nis not to be developer relationsâand I'd say things went well too!\"}),\"\\n\",n(a.p,{children:\"Last but not least, I've been to some really amazing conferences and, IMHO, many\\nthings went quite well!\"}),\"\\n\",t(a.p,{children:[\"So, that's what this post is about: sharing some lessons learned, a lot of\\n\",n(a.em,{children:\"âthat went wellâ\"}),\" and other exciting stuff.\"]}),\"\\n\",t(a.h2,{id:\"for-speakers\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#for-speakers\",children:n(a.span,{className:\"icon icon-link\"})}),\"For Speakers\"]}),\"\\n\",t(a.h3,{id:\"preparing-sessions\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#preparing-sessions\",children:n(a.span,{className:\"icon icon-link\"})}),\"Preparing Sessions\"]}),\"\\n\",n(a.p,{children:\"There's nothing set in stone here, and I'd say every speaker has their own very\\npersonal tricks \u0026 tips. Of course, there are always some common denominators\\nacross great sessions, like having a concise idea, a clear execution, etc.âbut\\nyou probably know that.\"}),\"\\n\",n(a.p,{children:\"I thought of sharing here some practices I did throughout 2022 more than in any\\nother year that I consider to play a key role in the execution of my talks.\"}),\"\\n\",t(a.h4,{id:\"better-structuring-the-session\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#better-structuring-the-session\",children:n(a.span,{className:\"icon icon-link\"})}),\"Better Structuring The Session\"]}),\"\\n\",n(a.p,{children:\"One great thing I've always overlooked is having a good, concise, outline of the\\npresentation from the very beginning.\"}),\"\\n\",n(a.p,{children:\"I'd say this practice has an easy adoption: you can start with a vague outline,\\ncontinuously work on it and throughout the process, it's going to help you fill\\nout a lot of gaps and build out the content for each of your sections until\\nthere are no blank spaces left.\"}),\"\\n\",n(a.p,{children:\"Overall, the structure will be more digestible in the end, not only for you but\\nalso for the program committees of the conferences you're submitting to, as many\\nof themâe.g., GitNation and CityJS conferencesâactually ask for an outline\\nincluding a more detailed description of the shape and structure of your talk.\"}),\"\\n\",n(a.p,{children:n(a.img,{src:\"/content/posts/2022-wrapped/cfp.jpg\",alt:\"Multiple CFPs\"})}),\"\\n\",t(a.p,{children:[\"When building the outline, I often structure the presentation following the\\n\",n(a.a,{href:\"https://tvtropes.org/pmwiki/pmwiki.php/Main/TheHerosJourney\",children:\"âHeroâs Journeyâ pattern\"}),\".\\nIt's a classic story structure, often employed in literature and film, that\\nfollows the tale of a protagonist as they embark on a transformative journey.\"]}),\"\\n\",t(a.p,{children:[\"Here's an example from my\\nâ\",n(a.a,{href:\"https://www.ythecombinator.space/talks/web-performance-apis-you-probably-didnt-know-existed\",children:\"Web Performance APIs That You
2(Probably) Never Knew Existed\"}),\"â\\nsession:\"]}),\"\\n\",t(a.ol,{children:[\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[n(a.strong,{children:\"An initial conflict\"}),\": A section that usually goes by \",n(a.em,{children:\"âA Little Bit of\\nContextâ\"}),\" or \",n(a.em,{children:\"âWhy Am I Here?â\"}),\". In this talk, the initial conflict is \",n(a.em,{children:\"âI\\nknow this set of performance best practices, and yet, I've seen these\\nproblems with our loading times metrics via Real User Monitoring.â\"})]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[n(a.strong,{children:\"Heroâs setup\"}),\": Here, we're making the audience think about our journey,\\nwith topics like web performance metrics and our path of investigating native\\nAPIs for collecting and improving performance.\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[n(a.strong,{children:\"Energy peak\"}),\" where we beat the villainâbad perceived performance. In this\\ntalk, these peaks frequently happen after the audience sees a given technique\\nand how it improved something, with examples and numbers.\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[n(a.strong,{children:\"Epiphany-alike closing ideas\"}),\" that will bring an enlightening realization\\nthat our performance problems can be understood from a new and more profound\\nperspective. In this talk, there are two sections responsible for this: \",n(a.em,{children:\"âWhy\\nare we here?â\"}),\", which promotes the reflection on why we should care about\\nperceived performance in the first place. Here, we have resources like\\nimpacting numbers and statistics about browsers, quality of connection,\\ndevices, etc., previous research about how this impacts peopleâs emotions,\\nand studies on how to correlate them all with business metrics. The other one\\nis \",n(a.em,{children:\"âClosing Notesâ\"}),\" where we wrap up with some key takeaways from the\\nsession.\"]}),\"\\n\"]}),\"\\n\"]}),\"\\n\",n(a.p,{children:\"In my personal experience, building the session within this framework makes it\\nmore interesting, increases audience engagement and in general, helps the\\nmessaging be more successful.\"}),\"\\n\",t(a.h4,{id:\"dry-runs\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#dry-runs\",children:n(a.span,{className:\"icon icon-link\"})}),\"Dry Runs\"]}),\"\\n\",n(a.p,{children:\"Back when I had my college entrance exams, I'd draft the whole essay idea on a\\nseparate piece of paper and that'd go around 50/60 lines of text. Then, I'd go\\nthrough the whole outline and key parts and cut it down to the allowed limit of\\n30 lines.\"}),\"\\n\",t(a.p,{children:[\"Once the first MVPâaka. \",n(a.em,{children:\"Minimum Viable Presentation\"}),\"âversion of the session is\\nready, I run it for the first time. And, just like those essays in high school,\\nthe first run is always larger than the allowed limit! So, this part is a lot\\nabout cutting off the outline, tweaking the slides, and iterating again.\"]}),\"\\n\",t(a.p,{children:[\"When I feel I have the first âpre-releaseâ of the session, I reach out to a few\\nfriends, schedule dry runs with them, and pretend it's the first time. I have a\\nfixed list of people I always go withâa huge shoutout to\\n\",n(a.a,{href:\"https://twitter.com/bmacabeus\",children:\"Macabeus\"}),\",\\n\",n(a.a,{href:\"https://twitter.com/tsirlucas\",children:\"Lucas\"}),\", and\\n\",n(a.a,{href:\"https://twitter.com/falcaoaugustos\",children:\"Augusto\"}),\"âand who always provide great\\nfeedback on different areas, like the overall visual aspect, my selection of\\ninformation and ideas, coherence throughout the session, the chosen level of\\ndetail and many others!\"]}),\"\\n\",n(a.p,{children:\"Last but not least, whenever I get an existing session approved for another\\nevent with a different time slot, I also run againâthis time, only on my ownâto\\nunderstand how much Iâll need to cut. Usually, two scenarios fit here:\"}),\"\\n\",t(a.ul,{children:[\"\\n\",t(a.li,{children:[\"\\n\",n(a.p,{children:\"Sessions that are originally 45/50/60 minutes longâmostly tailored for\\ngeneral-purpose conferences which have long slots, like the NDC eventsâand\\nneed to be cut to fit front-end/React conferences with slots like 25/30\\nminutes.\"}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",n(a.p,{children:\"Sessions that were 50/60 minutes long on my first rehearsals, had to be shrunk\\nto fit 25/30 minute slots and then got approved to larger slots and need to be\\nadapted again.\"}),\"\\n\"]}),\"\\n\"]}),\"\\n\",t(a.h4,{id:\"audience-interactions\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#audience-interactions\",children:n(a.span,{className:\"icon icon-link\"})}),\"Audience Interactions\"]}),\"\\n\",n(a.p,{children:n(a.img,{src:\"/content/posts/2022-wrapped/audience-interactions.jpg\",alt:\"Audience raising hands at React Day Berlin 2022\"})}),\"\\n\",n(a.p,{children:\"Last but not least, there's another practice that I've seen to increase audience\\nengagement is to turn your presentation into an open dialogue.\"}),\"\\n\",n(a.p,{children:\"I'd say there are a few different ways you can do this here:\"}),\"\\n\",t(a.h5,{id:\"1-contextualization-questions\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#1-contextualization-questions\",children:n(a.span,{className:\"icon icon-link\"})}),\"#1 Contextualization Questions\"]}),\"\\n\",n(a.p,{children:\"Here you get to understand your audience's technical background. Examples are:\"}),\"\\n\",t(a.ul,{children:[\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"checking who's familiar with modern front-end development in a \",n(a.strong,{children:\"generic IT\\nconference\"}),\";\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"checking how much of your audience are advanced React engineers in a \",n(a.strong,{children:\"generic\\nfront-end\"}),\" conference;\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"checking who's familiar with a specific bundler, testing library, etc. in a\\n\",n(a.strong,{children:\"React conference\"}),\".\"]}),\"\\n\"]}),\"\\n\"]}),\"\\n\",t(a.p,{children:[\"A few simple \",n(a.em,{children:\"âraise your handsâ\"}),\" questions might sound almost like sharing the\\nmic with every attendee and give you powerful insights to guide your whole\\npresentation strategy, including:\"]}),\"\\n\",t(a.ul,{children:[\"\\n\",t(a.li,{children:[\"\\n\",n(a.p,{children:\"how much time you should invest in explaining a given topic;\"}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",n(a.p,{children:\"whether you should spend some time addressing necessary previous knowledge;\"}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",n(a.p,{children:\"whether you should focus on diving deep into every aspect of one topic or\\nproviding just an overview with a high-level, example-driven, approach.\"}),\"\\n\"]}),\"\\n\"]}),\"\\n\",n(a.p,{children:\"Recent examples of this:\"}),\"\\n\",t(a.ul,{children:[\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"In \",n(a.a,{href:\"https://frontmania.com/\",children:\"Frontmania 2022\"}),\", I found out that a considerable\\npart of the audience was working mostly with Angular and Vue. Even though they\\nhad knowledge of React, given that my session\\n(â\",n(a.a,{href:\"https://www.ythecombinator.space/talks/inside-fiber-the-in-depth-overview-you-wanted-a-tldr-for\",children:\"Inside Fiber: the in-depth overview you wanted a TL
2DR for\"}),\"â)\\nwas a deep dive into the internals, I had to provide some extra context in\\nsome situations.\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"In \",n(a.a,{href:\"https://www.buildstuff.events/\",children:\"Build Stuff 2022\"}),\", I realized about 40% of\\nmy audience were primarily back-end engineers. Although my talk was\\nframework-agnostic, in some examples, I had React components. Because I was\\naware a huge percentage of them probably didn't have a lot of familiarity with\\nReact, I spent some extra time in these slides, detailing what was happening\\nthere.\"]}),\"\\n\"]}),\"\\n\"]}),\"\\n\",t(a.h5,{id:\"2-open-discussion-questions\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#2-open-discussion-questions\",children:n(a.span,{className:\"icon icon-link\"})}),\"#2 Open Discussion Questions\"]}),\"\\n\",n(a.p,{children:\"These are probably my favorite ones because you can always spark exciting\\ndiscussions and make the messaging of your talk more successful by gathering\\naudience opinions and hot takes on a
2specific topic. I've done this a few times\\nin my sessions, usually with tricky mental exercises:\"}),\"\\n\",t(a.ul,{children:[\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[n(a.em,{children:\"âIf you were to summarize web performance in one metric, whatâd be your\\npick?â\"}),\" I asked during my session\\nâ\",n(a.a,{href:\"https://www.ythecombinator.space/talks/web-performance-apis-you-probably-didnt-know-existed\",children:\"Web Performance APIs That You (Probably) Never Knew Existed\"}),\"â.\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[n(a.em,{children:\"âIf you were to summarize Concurrent React in one word/expression, whatâd be\\nyour pick?â\"}),\" during\\nâ\",n(a.a,{href:\"https://www.ythecombinator.space/talks/deep-diving-on-concurrent-react\",children:\"Deep diving on Concurrent React\"}),\"â\"]}),\"\\n\"]}),\"\\n\"]}),\"\\n\",n(a.p,{children:\"This also allows you to run detailed reports and analyze the results after the\\nconference. Then you can power the content/structure decisions we discussed a\\nfew paragraphs above for the upcoming talks with actual data/input from your\\naudience.\"}),\"\\n\",n(a.p,{children:\"In the example of the Concurrent React session, I was able to draft a few\\nconclusions on top of the results:\"}),\"\\n\",t(a.ul,{children:[\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"Thereâs still a lot of confusion around \",n(a.em,{children:\"âparallelismâ\"}),\", \",n(a.em,{children:\"âmultithreadingâ\"}),\",\\nand \",n(a.em,{children:\"âworkersâ\"}),\" vs the actual cooperative, single-rendering-threaded, model.\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"Results like \",n(a.em,{children:\"âpointlessâ\"}),\", \",n(a.em,{children:\"âmadnessâ\"}),\", and \",n(a.em,{children:\"âdifficultâ\"}),\", IMHO, show that\\nit's still not clear how all the features fit together just by looking at the\\nindividual pieces.\"]}),\"\\n\"]}),\"\\n\"]}),\"\\n\",n(a.p,{children:\"These will turn into long-term insights you can also use to engage the audience\\nafter the session, like when I built a report around the impressions above of\\nReact engineers over the new Concurrent React features.\"}),\"\\n\",n(a.p,{children:n(a.img,{src:\"/content/posts/2022-wrapped/results.jpg\",alt:\"Poll results\"})}),\"\\n\",t(a.p,{children:[\"Depending on what you use for your speaker decks, there are different\\ntechnologies you can choose to allow your audience to watch results come in live\\non the big screen. The best option I've found so far for Keynote was the\\n\",n(a.a,{href:\"https://www.polleverywhere.com\",children:\"Poll Everywhere\"}),\" plugin, which is also\\navailable for other platforms like PowerPoint and Google Slides.\"]}),\"\\n\",n(a.p,{children:\"Last but not least, this strategy is also great because it works whether you\\npresent virtually, in person, or in a hybrid environmentâwhich is getting more\\nand more common in this post-pandemic era.\"}),\"\\n\",t(a.h5,{id:\"3-tech-trivia-questions\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#3-tech-trivia-questions\",children:n(a.span,{className:\"icon icon-link\"})}),\"#3 Tech Trivia Questions\"]}),\"\\n\",t(a.p,{children:[\"I got this technique by watching a session about tricky/unexpected JavaScript\\nbehaviorsâsomething along the lines of\\n\",n(a.a,{href:\"https://www.destroyallsoftware.com/talks/wat\",children:\"Wat\"}),\"âby\\n\",n(a.a,{href:\"https://twitter.com/bmacabeus\",children:\"Macabeus\"}),\" about two years ago, where he would\\nplay with the audience using a live Kahoot trivia game.\"]}),\"\\n\",n(a.p,{children:\"I admit I loved the idea so much I decided to do something similar with my\\ncolleagues at Citrix back then, and I put their knowledge about JavaScript to\\nthe test with a similar, five-questions-based-quiz, session in one of our\\ninternal front-end meetings. We had some nerdy fun in the process and the\\nfeedback was great!\"}),\"\\n\",t(a.p,{children:[\"I never got another chance to prepare something similar ever since, but the\\ntechnique happened to be of great help this year at\\n\",n(a.a,{href:\"https://reactal
2icante.es\",children:\"React Alicante\"}),\", in September. I managed to convince\\nMedallia to sponsor the conferenceâmostly to raise our awareness and brand\\nvisibility among the Spanish front-end communityâand, as a part of the\\nsponsorship packages, we got a booth at the venue.\"]}),\"\\n\",n(a.p,{children:\"During the ideation of the activities we'd be doing at the booth, the Kahoot\\nidea popped up again and we decided to give it a try. We prepared some trivia\\nReact/TypeScript questions, targeting different seniority levels, and the result\\nwent way better than expected!\"}),\"\\n\",n(a.p,{children:n(a.img,{src:\"/content/posts/2022-wrapped/trivia.jpg\",alt:\"Tech Trivia at React Alicante\"})}),\"\\n\",n(a.p,{children:\"Everyone was hyped to test how much they knew about these technologies and learn\\na thing or two. The numbers went like this:\"}),\"\\n\",t(a.ul,{children:[\"\\n\",n(a.li,{children:\"~90 people playing the trivia;\"}),\"\\n\",n(a.li,{children:\"~10 rounds played during the coffee breaks;\"}),\"\\n\",n(a.li,{children:\"70+ Medallia t-shirts given away as prizes;\"}),\"\\n\",n(a.li,{children:\"12+ people filled out the form for working with us.\"}),\"\\n\"]}),\"\\n\",n(a.p,{children:\"I am looking forward to my next opportunity to try live tech quizzes again!\"}),\"\\n\",t(a.h3,{id:\"finding-events\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#finding-events\",children:n(a.span,{className:\"icon icon-link\"})}),\"Finding Events\"]}),\"\\n\",n(a.p,{children:\"One of the questions I get the most is how I manage to be aware of so many\\nevents and their Call For Papers. Well, luckily enough, there are plenty of\\nresources out there where one can hear about conferences. My list includes:\"}),\"\\n\",t(a.ul,{children:[\"\\n\",n(a.li,{children:n(a.a,{href:\"https://confs.tech\",children:\"https://confs.tech\"})}),\"\\n\",n(a.li,{children:n(a.a,{href:\"https://dev.events\",children:\"https://dev.events\"})}),\"\\n\",n(a.li,{children:n(a.a,{href:\"https://app.speakerhouse.io/events\",children:\"https://app.speakerhouse.io/events\"})}),\"\\n\",t(a.li,{children:[n(a.a,{href:\"https://sessionize.com\",children:\"https://sessionize.com\"}),\" (More specifically, it's \",n(a.em,{children:\"âDiscover Eventsâ\"}),\" tab that\\nspeakers have access to)\"]}),\"\\n\"]}),\"\\n\",t(a.h3,{id:\"orchestrating-sessions--events\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#orchestrating-sessions--events\",children:n(a.span,{className:\"icon icon-link\"})}),\"Orchestrating Sessions â© Events\"]}),\"\\n\",n(a.p,{children:\"Okay, now that we discussed the ideation process of a session and where to find\\nevents to present your fantastic talk at, we can explore the next step which is:\\nhow to coordinate the whole process of submitting different sessions across\\ndifferent events in different parts of the globe!\"}),\"\\n\",t(a.h4,{id:\"the-old-fashion\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#the-old-fashion\",children:n(a.span,{className:\"icon icon-link\"})}),\"The Old Fashion\"]}),\"\\n\",n(a.p,{children:\"First, I'd like to share my strategy for 2019-20. I had a Trello board with:\"}),\"\\n\",t(a.ul,{children:[\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[n(a.strong,{children:\"Four different lists\"}),\": \",n(a.em,{children:\"Proposals\"}),\", \",n(a.em,{children:\"Submitted\"}),\", \",n(a.em,{children:\"Rejected\"}),\", and\\n\",n(a.em,{children:\"Approved\"}),\".\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[n(a.strong,{children:\"Labels\"}),\" representing the conferences/meetups.\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[n(a.strong,{children:\"Cards\"}),\" representing the sessions that I'd copy-paste all over the four\\ndifferent categories above and label them accordingly.\"]}),\"\\n\"]}),\"\\n\"]}),\"\\n\",n(a.p,{children:n(a.img,{src:\"/content/posts/2022-wrapped/trello-board.png\",alt:\"Trello: Board with all the sessions\"})}),\"\\n\",n(a.p,{children:\"You could then think I'd have information for each of the sessions stored within\\nthe card for that session, right?\"}),\"\\n\",n(a.p,{children:n(a.img,{src:\"/content/posts/2022-wrapped/trello-card.png\",alt:\"Trello: Card for one session\"})}),\"\\n\",t(a.p,{children:[\"Nope! It turns out that Trello didn't have support for rich text descriptions of\\nthe cards back then. This was a dealbreaker for me, given that, when submitting\\na proposal, most of the conferences ask you for more information than a simple\\ntitle/abstract pair; it's fairly common to get prompted for stuff like an\\n\",n(a.strong,{children:\"elevator pitch\"}),\", \",n(a.strong,{children:\"keywords\"}),\", \",n(a.strong,{children:\"target audience\"}),\", \",n(a.strong,{children:\"required knowledge of\\nparticipants\"}),\", etc.\"]}),\"\\n\",t(a.p,{children:[\"To suppress this lack of \",n(a.em,{children:\"RTE\"}),\" support, I started then using Trello alongside\\nGoogle Documents.\"]}),\"\\n\",n(a.p,{children:n(a.img,{src:\"/content/posts/2022-wrapped/google-docs-talks.png\",alt:\"Google Docs: Session details\"})}),\"\\n\",n(a.p,{children:\"Last but not least, I had another Google Document where I'd keep my personal\\ndata useful for submitting, like current location, position, company, etc.\"}),\"\\n\",n(a.p,{children:n(a.img,{src:\"/content/posts/2022-wrapped/google-docs-bio.png\",alt:\"Google Docs: Personal details\"})}),\"\\n\",n(a.p,{children:\"I wasn't happy with the way things were going alreadyâit simply didn't scaleâand\\nwhen I faced myself about to add a third app to the equation (Google Calendar),\\nI decided it was about time to shift to something else.\"}),\"\\n\",t(a.h4,{id:\"the-new-fashion\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#the-new-fashion\",children:n(a.span,{className:\"icon icon-link\"})}),\"The New Fashion\"]}),\"\\n\",n(a.p,{children:\"There are a lot of productivity apps on the market. I had a shortlist of some of\\nthem that included Monday, ClickUp, Evernote, and Airtable.\"}),\"\\n\",n(a.p,{children:\"Because I was using Notion already to organize some personal stuff like\\ntraveling, I decided to give it a try as my all-in-one sessions â conferences\\nsolution.\"}),\"\\n\",n(a.p,{children:\"I start from the main sources I listed in the section aboveâI do check other\\nwebsites, but these are the best ones IMHO. I then gather and reconcile all the\\ndata in Notion. It looks like this:\"}),\"\\n\",n(a.p,{children:n(a.img,{src:\"/content/posts/2022-wrapped/notion-list.png\",alt:\"Notion: All sessions\"})}
2),\"\\n\",n(a.p,{children:\"This also helps me organize their status on a calendar:\"}),\"\\n\",n(a.p,{children:n(a.img,{src:\"/content/posts/2022-wrapped/notion-calendar.png\",alt:\"Notion: Calendar\"})}),\"\\n\",n(a.p,{children:\"Last but not least, I track which sessions I submitted to a given event so that\\nI can get a better understanding of the actual profile of this conference and\\nwhat kind of topics they tend to approve/reject.\"}),\"\\n\",n(a.p,{children:n(a.img,{src:\"/content/posts/2022-wrapped/notion-session.png\",alt:\"Notion: Info for each session\"})}),\"\\n\",n(a.p,{children:\"To be honest, I am still iterating on this approach but so far, I've enjoyed the\\nexperience! Among other stuff, I'd highlight in Notion:\"}),\"\\n\",t(a.ul,{children:[\"\\n\",n(a.li,{children:\"It's got huge flexibility and a delightful user experience;\"}),\"\\n\",n(a.li,{children:\"It's free for personal use;\"}),\"\\n\",n(a.li,{children:\"It does have some tools that enable you to have a certain level of project and\\ntask management in one place.\"}),\"\\n\"]}),\"\\n\",t(a.h2,{id:\"for-conference-organizers\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#for-conference-organizers\",children:n(a.span,{className:\"icon icon-link\"})}),\"For Conference Organizers\"]}),\"\\n\",n(a.p,{children:\"I have been involved in the organization of meetups and other small events in my\\nhometown back in 2015-18, but I never really got to organize anything for more\\nthan 100 people. Given that, my views here are more biased as both an attendee\\nand a speaker, but not an organizer.\"}),\"\\n\",n(a.p,{children:\"There are a bunch of different practices that result in a remarkable conference\\nexperience and I would never come up with an exhaustive list, but here are some\\nthings that certainly would make your event great!\"}),\"\\n\",t(a.h3,{id:\"budget\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#budget\",children:n(a.span,{className:\"icon icon-link\"})}),\"Budget\"]}),\"\\n\",n(a.p,{children:\"First and foremost, ensure you have all the basic stuff to be covered by your\\nbudget, including:\"}),\"\\n\",t(a.ul,{children:[\"\\n\",t(a.li,{children:[\"\\n\",n(a.p,{children:\"all the speaker expenses (traveling tickets, accommodation close to the\\nconference venue, commute from the airport to the hotel, etc.);\"}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",n(a.p,{children:\"speaker dinners and other fun activities;\"}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",n(a.p,{children:\"proper A/V and room setup (LED displays, proper lighting, etc.);\"}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",n(a.p,{children:\"food \u0026 drinks for everyone;\"}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",n(a.p,{children:\"staffâof course, here I mean those who are not volunteer work from the\\ncommunity.\"}),\"\\n\"]}),\"\\n\"]}),\"\\n\",t(a.h3,{id:\"audience-demographics\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#audience-demographics\",children:n(a.span,{className:\"icon icon-link\"})}),\"Audience Demographics\"]}),\"\\n\",t(a.p,{children:[\"Now that's something I had never seen in a conference and I have to say it was\\njust an incredible idea by the \",n(a.a,{href:\"https://www.reactindia.io\",children:\"React India team\"}),\"!\"]}),\"\\n\",n(a.p,{children:\"A few weeks before the event, they shared some anonymous statistics describing\\nthe audience, which included in-person and online attendance numbers, seniority\\nlevels (ranging from beginner to expert), and companies they were coming from.\"}),\"\\n\",n(a.p,{children:\"This demographic analysis is really helpful for speakers to consider their\\ncontent beforehand.\"}),\"\\n\",t(a.h3,{id:\"simple-feedback-system\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#simple-feedback-system\",children:n(a.span,{className:\"icon icon-link\"})}),\"Simple Feedback System\"]}),\"\\n\",n(a.p,{children:\"In my opinion, that's something most of the front-end/React events should learn\\nfrom multipurpose development ones.\"}),\"\\n\",n(a.p,{children:\"Usually, what you see out there are either some digital surveys emailed to the\\nattendees or feedback gathered in apps like Eventee. Although these are great\\nfor more complex analysis and fancy stuff like weighted averages, what I notice\\nis that unfortunately, only very few attendees take the time to fill out some\\nsort of survey, no matter if that's during or after the conference.\"}),\"\\n\",t(a.p,{children:[\"I've always wondered what would be a better way to do thatânot necessarily a\\nreplacement, perhaps a complementary solutionâ, until I went to\\n\",n(a.a,{href:\"https://devconf.pl/\",children:\"DevConf PL\"}),\" and saw that they had ballot drop boxes\\navailable for feedback during the talks. Throughout the year, I then realized\\nthat it seems to occur regularly in back-end driven events or generic software\\ndevelopment ones, after seeing the same system in conferences like\\n\",n(a.a,{href:\"https://ndcoslo.com/\",children:\"NDC Oslo\"}),\" or\\n\",n(a.a,{href:\"https://www.buildstuff.events/\",children:\"Build Stuff\"}),\".\"]}),\"\\n\",t(a.p,{children:[\"The voting ballots were colorful cards (\",n(a.span,{role:\"img\",\"aria-label\":\"\",\"aria-hidden\":!0,children:\"ð¢\"}),\" Green / \",n(a.span,{role:\"img\",\"aria-label\":\"\",\"aria-hidden\":!0,children:\"ð¡\"}),\" Yellow / \",n(a.span,{role:\"img\",\"aria-label\":\"red circle\",children:\"ð´\"}),\" Red) outside\\nthe room. They are counted after each of the sessions and then each speaker gets\\nan email after the conference wraps up with their numbers.\"]}),\"\\n\",n(a.p,{children:\"That simple!\"}),\"\\n\",t(a.h2,{id:\"accomplishments\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#accomplishments\",children:n(a.span,{className:\"icon icon-link\"})}),\"Accomplishments\"]}),\"\\n\",n(a.p,{children:n(a.img,{src:\"/content/posts/2022-wrapped/accomplishments.jpg\",alt:\"Me out there\"})}),\"\\n\",n(a.p,{children:\"I'd say this year brought a lot of new experiences and a ton of wins! I know\\nthis post is a bit long already, but I will share a few of them as I feel\\nfortunate and proud of them. Here you'll find some of those mentioned wins and\\nalso some not-so-great results.\"}),\"\\n\",t(a.ul,{children:[\"\\n\",t(a.li,{children:[\"I helped draft a developer communities program at Medallia from almost nothing\\nwith a fantastic crew and we went from zero to sponsoring three conferences:\\n\",n(a.a,{href:\"https://devconf.pl\",children:\"DevConf 2022\"}),\",\\n\",n(a.a,{href:\"https://www.reactindia.io/\",children:\"React India 2022\"}
2),\" and\\n\",n(a.a,{href:\"https://reactalicante.es\",children:\"React Alicante 2022\"}),\". We learned a lot together and\\nare still evolving. This is our Spanish squad in React Alicante! \",n(a.span,{role:\"img\",\"aria-label\":\"\",\"aria-hidden\":!0,children:\"ð¤©\"})]}),\"\\n\"]}),\"\\n\",n(a.p,{children:n(a.img,{src:\"/content/posts/2022-wrapped/medallia+react-alicante.jpg\",alt:\"Medallia at React Alicante\"})}),\"\\n\",t(a.ul,{children:[\"\\n\",t(a.li,{children:[\"\\n\",n(a.p,{children:\"I crafted eight different sessions, and four of them I managed to present\\nthroughout the year.\"}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"I submitted to \",n(a.strong,{children:\"41 conferences\"}),\" in \",n(a.strong,{children:\"25 locations\"}),\"âonline + 24\\ncountriesâand 34 cities. Out of these:\"]}),\"\\n\"]}),\"\\n\"]}),\"\\n\",t(a.p,{children:[n(a.span,{role:\"img\",\"aria-label\":\"smiling face with open mouth \u0026 cold sweat\",children:\"ð
\"}),\" In \",n(a.strong,{children:\"16\"}),\" of them, I was not accepted.\"]}),\"\\n\",t(a.p,{children:[n(a.span,{role:\"img\",\"aria-label\":\"\",\"aria-hidden\":!0,children:\"ð¤©\"}),\" In \",n(a.strong,{children:\"13\"}),\" of them I was approved and I managed to deliver the presentation\\nsuccessfully.\"]}),\"\\n\",t(a.p,{children:[n(a.span,{role:\"img\",\"aria-label\":\"\",\"aria-hidden\":!0,children:\"ð¤¦\"}),\" In \",n(a.strong,{children:\"8\"}),\" of them, I never heard back from the organization/committee. IMHO,\\nthis is a red flag that shows a considerable lack of respect for anyone who\\nspent some time writing down ideas and filling up CFP processes.\"]}),\"\\n\",t(a.p,{children:[n(a.span,{role:\"img\",\"aria-label\":\"disappointed but relieved face\",children:\"ð¥\"}),\" In \",n(a.strong,{children:\"4\"}),\" of them I was approved, but I had to withdraw my submission for\\nvarious reasons (e.g., because of calendar conflicts or personal issues).\"]}),\"\\n\",t(a.ul,{children:[\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"I traveled to \",n(a.strong,{children:\"10 different countries\"}),\".\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"I was invited to \",n(a.strong,{children:\"two podcasts\"}),\", one in English and one in Portugueseâthese\\nare yet to be published.\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"I was invited to write \",n(a.strong,{children:\"one magazine article\"}),\" about web performance.\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",n(a.p,{children:\"I improved my overall skills in writing/reviewing CFPs and preparing other\\nless-experienced speakers.\"}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",n(a.p,{children:\"Last but not least, I met dozens of amazing people who are now friends and who\\nI'm already hyped to see again.\"}),\"\\n\"]}),\"\\n\"]}),\"\\n\",t(a.h2,{id:\"closing-time\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#closing-time\",children:n(a.span,{className:\"icon icon-link\"})}),\"Closing Timeâ¦\"]}),\"\\n\",n(a.p,{children:\"Finally, I'd love to wish all of you out there a great Holiday Season! Happy\\nHolidays and a Happy New Year, everyone!\"}),\"\\n\",t(a.p,{children:[\"See you all next in 2023! \",n(a.span,{role:\"img\",\"aria-label\":\"fireworks\",children:\"ð\"})]})]})}return{default:function(e={}){const{wrapper:t}=e.components||{};return t?n(t,{...e,children:n(_createMdxContent,{...e})}):_createMdxContent(e)}};"},"_tags":["career","community","devrel"]},{"title":"Jheniffer was always my favorite color","date":"2020-08-20T00:00:00.000Z","summary":"I hope yall don't mind the inconvenience, but I need to talk about Jheniffer Rodrigues.","language":"en","tags":["life"],"slug":"jheniffer-was-always-my-favorite-color","hero":"/content/posts/jheniffer-was-always-my-favorite-color/hero.png","readingTime":{"text":"5 min read","minutes":4.585,"time":275100,"words":917},"body":{"code":"const{Fragment:e,jsx:n,jsxs:t}=arguments[0];function _createMdxContent(i){const h={a:\"a\",em:\"em\",li:\"li\",p:\"p\",strong:\"strong\",ul:\"ul\",...i.components};return t(e,{children:[n(h.p,{children:\"I hope yall don't mind the inconvenience, but I need to talk about Jheniffer\\nRodrigues.\"}),\"\\n\",t(h.p,{children:[\"Yup, you got it right. Not \",n(h.em,{children:\"Jennifer\"}),\", nor \",n(h.em,{children:\"Jeniffer\"}),\", \",n(h.em,{children:\"Jenniffer\"}),\", \",n(h.em,{children:\"Jenifer\"}),\",\\nor any other regularly spelled variation you could think of; this one goes by\\n\",n(h.em,{children:\"J-H-E-N-I-F-F-E-R\"}),\", with the H taking most of the work in representing how\\nunique she is â and putting all spell checkers, text editors, and my relatives\\non the same quest to properly spell it.\"]}
2),\"\\n\",n(h.p,{children:\"Before I start with my few hundreds of words of some loving cliché usual for\\nbirthdays, one quick heads-up for you, dear reader: this isn't 100% about her\\nbut also about the need I have to express what I feel â especially what I've\\nbeen feeling in the last few months â because I think it is only reasonable for\\neveryone else to know about the amazing person she is.\"}),\"\\n\",n(h.p,{children:\"I met her when were both sophomores in high school and nowadays she's the one\\nwho makes all my recipes go wrong because I get distracted with our never-ending\\nconversations in the kitchen. But that's not all!\"}),\"\\n\",t(h.ul,{children:[\"\\n\",t(h.li,{children:[\"Jheniffer loves miniature puppies, especially Chihuahuas and Pinschers â and\\nthat's how we managed to bring\\n\",n(h.a,{href:\"https://www.instagram.com/ricardo.domenico/\",children:\"Ricardo\"}),\" to our family;\"]}),\"\\n\",n(h.li,{children:\"Jheniffer hates coffee but she still goes to cafés with me â okay, it helps\\nconvincing when I promise I'll pay her a hot chocolate; she loves a good one;\"}),\"\\n\",n(h.li,{children:\"Jheniffer excels doing stuff on Excel â seriously I still haven't figured out\\nhow she manages to learn tricks there that fast;\"}),\"\\n\",n(h.li,{children:\"Jheniffer has some playlists on Spotify that bring a whole new meaning to my\\ndefinitions of being eclectic;\"}),\"\\n\",n(h.li,{children:\"Jheniffer cooks the best Pasta ai Quattro Formaggi one could ever taste. And\\nplease, don't make me talk about her chicken wings or her desserts!\"}),\"\\n\",n(h.li,{children:\"Jheniffer is also the one who convinced me that gnocchi and spinach is\\nactually a good thing to try â and this made me become a gnocchi-person;\"}),\"\\n\",n(h.li,{children:\"Jheniffer, for some reason, thinks that Czech is more beginners-friendly than\\nEnglish â and I can't even say how much this puzzles me;\"}),\"\\n\",n(h.li,{children:\"Jheniffer throws facts and curiosities about the human body on random\\nconversations â those she learned when taking speech-language pathology\\nlessons;\"}),\"\\n\",n(h.li,{children:\"Jheniffer dreams of visiting as many countries as possible, including Hungary,\\nRomania, Finland, Greece, and Maldivas;\"}),\"\\n\",t(h.li,{children:[\"Jheniffer has likely been through the whole Netflix catalog; in more than one\\ncountry â but when she's puzzled by a movie's plot, it always means we'll have\\nto watch it together. You know what they say⦠\",n(h.em,{children:'\"Two heads are better than\\none\"'}),\";\"]}),\"\\n\",n(h.li,{children:\"Jheniffer slaps me if I miss one frame of any movie we're watching together;\"}),\"\\n\",n(h.li,{children:\"Jheniffer has already been through my crises and she didn't give up on me; she\\ncame along and stayed with me till I calmed down;\"}),\"\\n\",n(h.li,{children:\"Jheniffer judges me 24/7 when I'm doing housework, finding imperfections even\\nin the way I do the dishes;\"}),\"\\n\",n(h.li,{children:\"Jheniffer eats sugary stuff and goes shopping when she's stressed out â me\\nbeing 50% of the reasons why she's stressed out;\"}),\"\\n\",n(h.li,{children:\"Jheniffer is one of the most hard-working people I've ever met;\"}),\"\\n\",n(h.li,{children:\"Jheniffer is the best one I know in coming up with handcrafted surprises for\\nbirthdays, anniversaries, and other celebrations.\"}),\"\\n\"]}),\"\\n\",n(h.p,{children:\"By the way, the last bullet on the list is actually why any effort with these\\nparagraphs here won't outcome something as amazing as what she would come up\\nwith if it were her trying to make a birthday surprise.\"}),\"\\n\",n(h.p,{children:\"I want to give it a shot, still. So⦠Happy birthday to her! Today I love her\\nmore than yesterday and tomorrow I will love her more than today, cause she's\\none of the kind who shines, captivates, and surprises. She's a lovely woman and\\nI... I am in love with her!\"}),\"\\n\",n(h.p,{children:\"I admit the world itself right now isn't in the perfect scenario to celebrate\\nanother year of her life and the last few months haven't been easy, either. We\\nall are going through something challenging â and quite terrible, to be honest\\nâ, but at the same time, this whole thing showed me how privileged I am to have\\nsomeone like her by my side.\"}),\"\\n\",n(h.p,{children:\"I can't even put into words how much I am looking forward to all the incredible\\nmoments that we are still going to have â and I am aware of the tough times that\\nwill come, but what matters is that we spend all of these together.\"}),\"\\n\",n(h.p,{children:\"Obviously, our relationship also challenges us, but in the end, we improve and\\nexpand each other's universe. She encourages me, helps me discover the best\\nthings, and together we come up with whatever is missing.\"}),\"\\n\",n(h.p,{children:\"Obviously, Jheniffer still exists with no Matheus and Matheus still exists with\\nno Jheniffer. But I honestly admit that my favorite version of each other is\\nwhen we are together. And by her side is how I want to be to see her conquer the\\nwhole world!\"}),\"\\n\",n(h.p,{children:\"I started writing this essay for Jheniffer â my wife â and I realized that we\\nmight decide to follow different paths, one day. Then I figured out that I'm\\nreally writing this essay for Jheniffer â a person I can't even say how much I\\nadmire and how lucky family and friends are to have in life â, because\\nrelationships might always face an end, but this thing⦠This shall never end.\"}),\"\\n\",t(h.p,{children:[n(h.strong,{children:\"Jheniffer, you've always been my favorite color\"}),\".\"]})]})}return{default:function(e={}){const{wrapper:t}=e.components||{};return t?n(t,{...e,children:n(_createMdxContent,{...e})}):_createMdxContent(e)}};"},"_tags":["life"]},{"title":"Driving towards a universal navigation strategy in React","date":"2020-01-13T00:00:00.000Z","summary":"When I joined STRV, they had a specific request for me; to build a front-end app for iOS, Android, and Web, sharing component and business logic amongst all the platforms.","language":"en","tags":["react","react native","navigation"],"slug":"driving-towards-a-universal-navigation-strategy-in-react","hero":"/content/posts/driving-towards-a-universal-navigation-strategy-in-react/hero.png","readingTime":{"text":"8 min read","minutes":7.775,"time":466500,"words":1555},"body":{"code":"const{Fragment:e,jsx:n,jsxs:a}=arguments[0];function _createMdxContent(t){const i={a:\"a\",blockquote:\"blockquote\",code:\"code\",em:\"em\",h2:\"h2\",h3:\"h3\",li:\"li\",ol:\"ol\",p:\"p\",pre:\"pre\",span:\"span\",ul:\"ul\",...t.components};return a(e,{children:[a(i.p,{children:[\"When I joined \",n(i.a,{href:\"https://www.strv.com\",children:\"STRV\"}),\", they had a specific request for me;\\nto build a front-end app for iOS, Android, and Web, sharing component and\\nbusiness logic amongst all the platforms.\"]}),\"\\n\",n(i.p,{children:\"Since Iâm a front-end developer who loves new areas, I couldnât say no and I had\\nto jump at the opportunity.\"}),\"\\n\",n(i.p,{children:\"I ended up facing many different challenges; from lack of real-world-scenarios\\ncontent related to React Native Web to unexpected lack of documented stuff on\\npopular projects, to struggling to build some platform-specific modules.\"}),\"\\n\",n(i.p,{children:\"And this post is focused on â a very important â part of this journey: building\\na navigation solution.\"}),\"\\n\",n(i.p,{children:\"But first...\"}),\"\\n\",a(i.h2,{id:\"a-bit-of-context\",children:[n(i.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#a-bit-of-context\",children:n(i.span,{className:\"icon icon-link\"})}),\"A bit of context\"]}
2),\"\\n\",n(i.p,{children:\"I had only worked on an example React Native app before (uncompiled and\\nunpublished). At the time of this project, I didnât know much about React\\nNative, to be honest.\"}),\"\\n\",a(i.p,{children:[\"I first heard of \",n(i.a,{href:\"https://expo.io/\",children:\"Expo\"}),\" and its experimental web\\nsupport\",\"1\",\" but I decided not to go for it mostly because I enjoy having\\ncontrol over the project stack and being aware of what's happening; I want to be\\nable to customize the installation, install custom versions of modules and have\\nmore control of project dependencies.\"]}),\"\\n\",a(i.p,{children:[\"I then heard of two other initiatives on Github:\\n\",n(i.a,{href:\"https://github.com/necolas/react-native-web\",children:\"ReactNative for Web\"}),\" and\\n\",n(i.a,{href:\"https://github.com/microsoft/reactxp\",children:\"ReactXP\"}),\". Both share similar goals but\\nthe approaches differ. As the official documentation for ReactXP states:\"]}),\"\\n\",a(i.blockquote,{children:[\"\\n\",n(i.p,{children:\"ReactXP is a layer that sits on top of React Native and React, whereas React\\nNative for Web is a parallel implementation of React Native â a sibling to\\nReact Native for iOS and Android.\"}),\"\\n\"]}),\"\\n\",n(i.p,{children:\"This post won't focus on covering the differences between these two but, after\\ngoing through some technical blog posts and talks, we ended up going for\\nReactNative for Web.\"}),\"\\n\",a(i.p,{children:[\"After a bit of digging into articles and trying to implement each environment in\\nits own realm, I found that for me, the best starting point was a great\\ntemplate, called\\n\",n(i.a,{href:\"https://github.com/brunolemos/react-native-web-monorepo\",children:\"react-native-web-monorepo\"}),\"2\",\",\\nwhich brings support for universal apps using a little help from\\n\",n(i.a,{href:\"https://yarnpkg.com/lang/en/docs/workspaces/\",children:\"Yarn Workspaces\"}),\".\"]}),\"\\n\",n(i.p,{children:\"Before starting to implement this approach into your project, though, I would\\nsuggest reviewing your requirements and checking whether these tools solve all\\nof your needs.\"}),\"\\n\",a(i.h2,{id:\"what-we-have-out-there\",children:[n(i.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#what-we-have-out-there\",children:n(i.span,{className:\"icon icon-link\"})}),\"What we have out there\"]}),\"\\n\",a(i.p,{children:[\"Some popular routing solutions on the React.js ecosystem were not meant to\\nsupport both DOM and native environments; \",n(i.code,{children:\"\u003cdiv\u003e\"}),\"s are different from \",n(i.code,{children:\"\u003cView\u003e\"}),\"s,\\n\",n(i.code,{children:\"\u003cul\u003e\"}),\"s are different from \",n(i.code,{children:\"\u003cFlatList\u003e\"}),\"s and most of the web primitives are\\ndifferent from the mobile ones â which makes it difficult to come up with a\\nuniversal solution. \",n(i.a,{href:\"https://reach.tech/router\",children:\"@reach/router\"}),\" is one example of\\nweb solutions that have opted not to face the challenges of supporting both\\nenvironments.\"]}),\"\\n\",n(i.p,{children:\"As of now (January 2020), though, we have a few ready universal web/native\\nformulas. But they all ended not serving completely our needs:\"}),\"\\n\",a(i.ul,{children:[\"\\n\",a(i.li,{children:[n(i.a,{href:\"https://github.com/ReactTraining/react-router\",children:\"react-router\"}),\" is a great\\noption for the web, but when on\\n\",n(i.a,{href:\"https://reacttraining.com/react-router/native\",children:\"mobile\"}),\", it lacks screen\\ntransitions, modals, navbar, back-button support, and other essential\\nnavigation primitives.\"]}),\"\\n\",a(i.li,{children:[n(i.a,{href:\"https://reactnavigation.org/\",children:\"react-navigation\"}),\" suits great on mobile but\\ngiven its \",n(i.a,{href:\"https://reactnavigation.org/docs/en/web-support.html\",children:\"web\"}),\" support\\nis still considered to be experimental â and has not yet been widely used in\\nproduction â it's very likely you're going to face a few issues\",\"3\",\"\\nrelated to history and query parameters. Also, it lacked TypeScript typings â\\nwhich made me write part of the definitions on my own since TypeScript was a\\nmust-have for the project.\"]}),\"\\n\"]}),\"\\n\",n(i.p,{children:\"And this brings us to the next part!\"}),\"\\n\",a(i.h2,{id:\"thinking-of-a-solution\",children:[n(i.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#thinking-of-a-solution\",children:n(i.span,{className:\"icon icon-link\"})}),\"Thinking of a solution\"]}),\"\\n\",a(i.blockquote,{children:[\"\\n\",a(i.p,{children:[\"The code from this post is available on GitHub:\\n\",n(i.a,{href:\"https://github.com/ythecombinator/react-native-web-monorepo-navigation\",children:\"ythecombinator/react-native-web-monorepo-navigation\"})]}),\"\\n\"]}),\"\\n\",a(i.p,{children:[\"I admit one of the most puzzling things when we dived into this journey was not\\nbeing able to find how popular apps out there using React Native for Web (e.g.\\nTwitter, Uber Eats and all the others mentioned\\n\",n(i.a,{href:\"https://github.com/necolas/react-native-web#react-native-for-web\",children:\"here\"}),\") are\\ndoing navigation â and how they faced challenges like the ones I mentioned\\nbefore.\"]}),\"\\n\",n(i.p,{children:\"So we had to work on our own!\"}),\"\\n\",a(i.p,{children:[\"Our new solution was based on abstracting on top of the most recent releases of\\nreact-router-dom\",\"4\",\" and react-navigation\",\"5\",\". Both evolved a\\nlot and now them two seem to share a few goals which I consider to be\\nkey-decisions for properly doing navigation/routing in React:\"]}),\"\\n\",a(i.ul,{children:[\"\\n\",n(i.li,{children:\"Hooks-first API\"}),\"\\n\",n(i.li,{children:\"Declarative way to implement navigation\"}),\"\\n\",n(i.li,{children:\"First-class types with TypeScript\"}),\"\\n\"]}),\"\\n\",n(i.p,{children:\"Given that, we came up with a couple of utils and components which aim a\\nuniversal navigation strategy:\"}),\"\\n\",a(i.h3,{id:\"utilsnavigation\",children:[n(i.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#utilsnavigation\",children:n(i.span,{className:\"icon icon-link\"})}),n(i.a,{href:\"https://github.com/ythecombinator/react-native-web-monorepo-navigation/blob/master/packages/components/src/utils/navigation\",children:n(i.code,{children:\"utils/navigation\"})})]}),\"\\n\",n(i.p,{children:\"Exposes two hooks:\"}),\"\\n\",a(i.ul,{children:[\"\\n\",a(i.li,{children:[\"\\n\",a(i.p,{children:[n(i.code,{children:\"useNavigation\"}
2),\": which returns a \",n(i.code,{children:\"navigate\"}),\" function that gets a route as a\\nfirst param and parameters as other arguments.\"]}),\"\\n\",n(i.p,{children:\"It can be used like this:\"}),\"\\n\",n(i.pre,{className:\"language-tsx\",children:a(i.code,{className:\"language-tsx code-highlight\",children:[a(i.span,{className:\"code-line\",children:[n(i.span,{className:\"token keyword\",children:\"import\"}),\" \",a(i.span,{className:\"token imports\",children:[n(i.span,{className:\"token punctuation\",children:\"{\"}),\" useNavigation \",n(i.span,{className:\"token punctuation\",children:\"}\"})]}),\" \",n(i.span,{className:\"token keyword\",children:\"from\"}),\" \",n(i.span,{className:\"token string\",children:\"'../utils/navigation'\"}),n(i.span,{className:\"token punctuation\",children:\";\"}),\"\\n\"]}),a(i.span,{className:\"code-line\",children:[n(i.span,{className:\"token comment\",children:\"// Our routes mapping â we'll be discussing about this one in a minute\"}),\"\\n\"]}),a(i.span,{className:\"code-line\",children:[n(i.span,{className:\"token keyword\",children:\"import\"}),\" \",a(i.span,{className:\"token imports\",children:[n(i.span,{className:\"token punctuation\",children:\"{\"}),\" routes \",n(i.span,{className:\"token punctuation\",children:\"}\"})]}),\" \",n(i.span,{className:\"token keyword\",children:\"from\"}),\" \",n(i.span,{className:\"token string\",children:\"'../utils/router'\"}),n(i.span,{className:\"token punctuation\",children:\";\"}),\"\\n\"]}),n(i.span,{className:\"code-line\",children:\"\\n\"}),a(i.span,{className:\"code-line\",children:[n(i.span,{className:\"token keyword\",children:\"const\"}),\" \",n(i.span,{className:\"token punctuation\",children:\"{\"}),\" navigate \",n(i.span,{className:\"token punctuation\",children:\"}\"}),\" \",n(i.span,{className:\"token operator\",children:\"=\"}),\" \",n(i.span,{className:\"token function\",children:\"useNavigation\"}),n(i.span,{className:\"token punctuation\",children:\"(\"}),n(i.span,{className:\"token punctuation\",children:\")\"}),n(i.span,{className:\"token punctuation\",children:\";\"}),\"\\n\"]}),n(i.span,{className:\"code-line\",children:\"\\n\"}),a(i.span,{className:\"code-line\",children:[n(i.span,{className:\"token comment\",children:\"// Using the `navigate` method from useNavigation to go to a certain route\"}),\"\\n\"]}),a(i.span,{className:\"code-line\",children:[n(i.span,{className:\"token function\",children:\"navigate\"}),n(i.span,{className:\"token punctuation\",children:\"(\"}),\"routes\",n(i.span,{className:\"token punctuation\",children:\".\"}),n(i.span,{className:\"token property-access\",children:\"features\"}),n(i.span,{className:\"token punctuation\",children:\".\"}),n(i.span,{className:\"token property-access\",children:\"codeSharing\"}),n(i.span,{className:\"token punctuation\",children:\".\"}),n(i.span,{className:\"token property-access\",children:\"path\"}),n(i.span,{className:\"token punctuation\",children:\")\"}),n(i.span,{className:\"token punctuation\",children:\";\"}),\"\\n\"]})]})}),\"\\n\",a(i.p,{children:[\"It also provides you with a few other known routing utilities like \",n(i.code,{children:\"goBack\"}),\"\\nand \",n(i.code,{children:\"replace\"}),\".\"]}),\"\\n\"]}),\"\\n\",a(i.li,{children:[\"\\n\",a(i.p,{children:[n(i.code,{children:\"useRoute\"}),\": which returns some data about the current route (e.g. \",n(i.code,{children:\"path\"}),\" and\\n\",n(i.code,{children:\"params\"}),\" passed to that route).\"]}),\"\\n\",a(i.p,{children:[\"This is how it could be used to get the current \",n(i.code,{children:\"path\"}),\":\"]}),\"\\n\",n(i.pre,{className:\"language-tsx\",children:a(i.code,{className:\"language-tsx code-highlight\",children:[a(i.span,{className:\"code-line\",children:[n(i.span,{className:\"token keyword\",children:\"import\"}),\" \",a(i.span,{className:\"token imports\",children:[n(i.span,{className:\"token punctuation\",children:\"{\"}),\" useRoute \",n(i.span,{className:\"token punctuation\",children:\"}\"})]}),\" \",n(i.span,{className:\"token keyword\",children:\"from\"}),\" \",n(i.span,{className:\"token string\",children:\"'../utils/navigation'\"}),n(i.span,{className:\"token punctuation\",children:\";\"}),\"\\n\"]}),n(i.span,{className:\"code-line\",children:\"\\n\"}),a(i.span,{className:\"code-line\",children:[n(i.span,{className:\"token keyword\",children:\"const\"}),\" \",n(i.span,{className:\"token punctuation\",children:\"{\"}),\" path \",n(i.span,{className:\"token punctuation\",children:\"}\"}),\" \",n(i.span,{className:\"token operator\",children:\"=\"}),\" \",n(i.span,{className:\"token function\",children:\"useRoute\"}),n(i.span,{className:\"token punctuation\",children:\"(\"}),n(i.span,{className:\"token punctuation\",children:\")\"}),n(i.span,{className:\"token punctuation\",children:\";\"}),\"\\n\"]}),n(i.span,{className:\"code-line\",children:\"\\n\"}),a(i.span,{className:\"code-line\",children:[n(i.span,{className:\"token console class-name\",children:\"console\"}),n(i.span,{className:\"token punctuation\",children:\".\"}),n(i.span,{className:\"token method function property-access\",children:\"log\"}),n(i.span,{className:\"token punctuation\",children:\"(\"}),\"path\",n(i.span,{className:\"token punctuation\",children:\")\"}),n(i.span,{className:\"token punctuation\",children:\";\"}),\"\\n\"]}),n(i.span,{className:\"code-line\",children:\"\\n\"}),a(i.span,{className:\"code-line\",children:[n(i.span,{className:\"token comment\",children:\"// This will log:\"}),\"\\n\"]}),a(i.span,{className:\"code-line\",children:[n(i.span,{className:\"token comment\",children:\"// '/features/code-sharing' on the web\"}),\"\\n\"]}),a(i.span,{className:\"code-line\",children:[n(i.span,{className:\"token comment\",children:\"// 'features_code-sharing' on mobile\"}),\"\\n\"]})]})}),\"\\n\"]}),\"\\n\"]}),\"\\n\",a(i.h3,{id:\"utilsrouter\",children:[n(i.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#utilsrouter\",children:n(i.span,{className:\"icon icon-link\"})}),n(i.a,{href:\"https://github.com/ythecombinator/react-native-web-monorepo-navigation/tree/master/packages/components/src/utils/router\",children:n(i.code,{children:\"utils/router\"})})]}),\"\\n\",a(i.p,{children:[\"This basically contains a \",n(i.co
2de,{children:\"routes\"}),\" object â which contains different paths and\\nimplementations for each platform â that can be used for:\"]}),\"\\n\",a(i.ul,{children:[\"\\n\",a(i.li,{children:[\"Navigating with \",n(i.code,{children:\"useNavigation\"})]}),\"\\n\",a(i.li,{children:[\"Switching logic based on the current route with \",n(i.code,{children:\"useRoute\"})]}),\"\\n\",a(i.li,{children:[\"Specifying the \",n(i.code,{children:\"path\"}),\" â and some extra data â of each route rendered by the\\n\",n(i.code,{children:\"Router\"}),\" component\"]}),\"\\n\"]}),\"\\n\",a(i.h3,{id:\"componentslink\",children:[n(i.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#componentslink\",children:n(i.span,{className:\"icon icon-link\"})}),n(i.a,{href:\"https://github.com/ythecombinator/react-native-web-monorepo-navigation/tree/master/packages/components/src/Link\",children:n(i.code,{children:\"components/Link\"})})]}),\"\\n\",a(i.p,{children:[\"It provides declarative navigation around the application. It is built on top of\\n\",n(i.code,{children:\"Link\"}),\" from \",n(i.code,{children:\"react-router-dom\"}),\"\\n\",n(i.a,{href:\"https://github.com/ythecombinator/react-native-web-monorepo-navigation/blob/master/packages/components/src/Link/index.web.tsx\",children:\"on web\"}),\"\\nand \",n(i.code,{children:\"TouchableOpacity\"}),\" + \",n(i.code,{children:\"useNavigation\"}),\" hook\\n\",n(i.a,{href:\"https://github.com/ythecombinator/react-native-web-monorepo-navigation/blob/master/packages/components/src/Link/index.native.tsx\",children:\"on mobile\"}),\".\"]}),\"\\n\",a(i.p,{children:[\"Just like \",n(i.code,{children:\"Link\"}),\" from \",n(i.code,{children:\"react-router-dom\"}),\", it can be used like this:\"]}),\"\\n\",n(i.pre,{className:\"language-tsx\",children:a(i.code,{className:\"language-tsx code-highlight\",children:[a(i.span,{className:\"code-line\",children:[n(i.span,{className:\"token keyword\",children:\"import\"}),\" \",a(i.span,{className:\"token imports\",children:[n(i.span,{className:\"token punctuation\",children:\"{\"}),\" \",n(i.span,{className:\"token maybe-class-name\",children:\"Text\"}),\" \",n(i.span,{className:\"token punctuation\",children:\"}\"})]}),\" \",n(i.span,{className:\"token keyword\",children:\"from\"}),\" \",n(i.span,{className:\"token string\",children:\"'react-native'\"}),n(i.span,{className:\"token punctuation\",children:\";\"}),\"\\n\"]}),n(i.span,{className:\"code-line\",children:\"\\n\"}),a(i.span,{className:\"code-line\",children:[n(i.span,{className:\"token keyword\",children:\"import\"}),\" \",a(i.span,{className:\"token imports\",children:[n(i.span,{className:\"token punctuation\",children:\"{\"}),\" \",n(i.span,{className:\"token maybe-class-name\",children:\"Link\"}),\" \",n(i.span,{className:\"token punctuation\",children:\"}\"})]}),\" \",n(i.span,{className:\"token keyword\",children:\"from\"}),\" \",n(i.span,{className:\"token string\",children:\"'../Link'\"}),n(i.span,{className:\"token punctuation\",children:\";\"}),\"\\n\"]}),a(i.span,{className:\"code-line\",children:[n(i.span,{className:\"token keyword\",children:\"import\"}),\" \",a(i.span,{className:\"token imports\",children:[n(i.span,{className:\"token punctuation\",children:\"{\"}),\" routes \",n(i.span,{className:\"token punctuation\",children:\"}\"})]}),\" \",n(i.span,{className:\"token keyword\",children:\"from\"}),\" \",n(i.span,{className:\"token string\",children:\"'../utils/router'\"}),n(i.span,{className:\"token punctuation\",children:\";\"}),\"\\n\"]}),n(i.span,{className:\"code-line\",children:\"\\n\"}),a(i.span,{className:\"code-line\",children:[a(i.span,{className:\"token tag\",children:[a(i.span,{className:\"token tag\",children:[n(i.span,{className:\"token punctuation\",children:\"\u003c\"}),n(i.span,{className:\"token class-name\",children:\"Link\"})]}),\" \",n(i.span,{className:\"token attr-name\",children:\"path\"}),a(i.span,{className:\"token script language-javascript\",children:[n(i.span,{className:\"token script-punctuation punctuation\",children:\"=\"}),n(i.span,{className:\"token punctuation\",children:\"{\"}),\"routes\",n(i.span,{className:\"token punctuation\",children:\".\"}),n(i.span,{className:\"token property-access\",children:\"features\"}),n(i.span,{className:\"token punctuation\",children:\".\"}),n(i.span,{className:\"token property-access\",children:\"webSupport\"}),n(i.span,{className:\"token punctuation\",children:\".\"}),n(i.span,{className:\"token property-access\",children:\"path\"}),n(i.span,{className:\"token punctuation\",children:\"}\"})]}),n(i.span,{className:\"token punctuation\",children:\"\u003e\"})]}),n(i.span,{className:\"token plain-text\",children:\"\\n\"})]}),a(i.span,{className:\"code-line\",children:[n(i.span,{className:\"token plain-text\",children:\" \"}),a(i.span,{className:\"token tag\",children:[a(i.span,{className:\"token tag\",children:[n(i.span,{className:\"token punctuation\",children:\"\u003c\"}),n(i.span,{className:\"token class-name\",children:\"Text\"})]}),n(i.span,{className:\"token punctuation\",children:\"\u003e\"})]}),n(i.span,{className:\"token plain-text\",children:'Check \"Web support via react-native-web\"'}),a(i.span,{className:\"token tag\",children:[a(i.span,{className:\"token tag\",children:[n(i.span,{className:\"token punctuation\",children:\"\u003c/\"}),n(i.span,{className:\"token class-name\",children:\"Text\"})]}),n(i.span,{className:\"token punctuation\",children:\"\u003e\"})]}),n(i.span,{className:\"token plain-text\",children:\"\\n\"})]}),a(i.span,{className:\"code-line\",children:[n(i.span,{className:\"token plain-text\"}),a(i.span,{className:\"token tag\",children:[a(i.span,{className:\"token tag\",children:[n(i.span,{className:\"token punctuation\",children:\"\u003c/\"}),n(i.span,{className:\"token class-name\",children:\"Link\"})]}),n(i.span,{className:\"token punctuation\",children:\"\u003e\"})]}),n(i.span,{className:\"token punctuation\",children:\";\"}),\"\\n\"]})]})}),\"\\n\",a(i.h3,{id:\"componentsrouter\",children:[n(i.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#componentsrouter\",children:n(i.span,{className:\"icon icon-link\"})}),n(i.a,{href:\"https://github.com/ythecombinator/react-native-web-monorepo-navigation/tree/master/packages/components/src/Router\",children:n(i.code,{children:\"components/Router\"})})]}),\"\\n\",a(i.p,{children:[\"This is the router itself. On the web, it's basically a \",n(i.co
2de,{children:\"BrowserRouter\"}),\", using\\n\",n(i.code,{children:\"Switch\"}),\" to pick a route. On mobile, it's a combination of both \",n(i.code,{children:\"Stack\"}),\" and\\n\",n(i.code,{children:\"BottomTab\"}),\" navigators.\"]}),\"\\n\",a(i.p,{children:[\"Wrapping up everything above, what you get is going through each\\n\",n(i.a,{href:\"https://github.com/ythecombinator/react-native-web-monorepo-navigation/tree/master/packages/components/src/screens\",children:\"screen\"}),\"\\nof the app and seeing how \",n(i.code,{children:\"useRoute()\"}),\", \",n(i.code,{children:\"useNavigation()\"}),\" and \",n(i.code,{children:\"\u003cLink /\u003e\"}),\" can be\\nused regardless of the platform you are.\"]}),\"\\n\",n(i.p,{children:\"If I was asked about future work on this, I'd mention as next steps:\"}),\"\\n\",a(i.ol,{children:[\"\\n\",a(i.li,{children:[\"\\n\",a(i.p,{children:[\"Adding more utilities â e.g. a \",n(i.code,{children:\"Redirect\"}),\" component aiming at a more\\ndeclarative navigation approach\",\"6\"]}),\"\\n\"]}),\"\\n\",a(i.li,{children:[\"\\n\",n(i.p,{children:\"Tackling edge cases on both platforms\"}),\"\\n\"]}),\"\\n\",a(i.li,{children:[\"\\n\",a(i.p,{children:[\"Reorganizing most of the things inside a navigation library and leaving only\\nthe main \",n(i.code,{children:\"Router\"}),\" component and \",n(i.code,{children:\"utils/router\"}),\" to be written on the\\napplication side.\"]}),\"\\n\"]}),\"\\n\"]}),\"\\n\",a(i.h2,{id:\"conclusions\",children:[n(i.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#conclusions\",children:n(i.span,{className:\"icon icon-link\"})}),\"Conclusions\"]}),\"\\n\",a(i.p,{children:[\"My feeling is that web, mobile web, and native application environments all\\nrequire a specific design and user experience\",\"7\",\" â and by the way, this\\nmatches the mentioned \",n(i.em,{children:\"âlearn once, write anywhereâ\"}),\"\\n\",n(i.a,{href:\"https://reactjs.org/blog/2015/03/26/introducing-react-native.html\",children:\"philosophy behind React Native\"}),\".\"]}),\"\\n\",n(i.p,{children:\"Although codesharing is a great advantage to React and React Native, I'd say\\nthat it is very likely that shared cross-platform code should be:\"}),\"\\n\",a(i.ul,{children:[\"\\n\",n(i.li,{children:\"Business Logic\"}),\"\\n\",n(i.li,{children:\"Config files, translation files, and most constant data â those that are not\\nrender-environment-specific\"}),\"\\n\",n(i.li,{children:\"API / Formatting; e.g. API calls, authentication and formatting of request and\\nresponse data\"}),\"\\n\"]}),\"\\n\",a(i.p,{children:[\"A few other layers of the app, like routing, should use a library that is most\\nappropriate for the platform, i.e. \",n(i.code,{children:\"react-router-dom\"}),\" for web, and\\n\",n(i.code,{children:\"react-navigation\"}),\" or similar for native.\"]}),\"\\n\",n(i.p,{children:\"Perhaps in the future, we can have a truly unified code base, but for now, it\\ndoesn't feel like the technology is ready and the approach shared here seemed to\\nbe the most suitable one.\"}),\"\\n\",a(i.h2,{id:\"footnotes\",children:[n(i.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#footnotes\",children:n(i.span,{className:\"icon icon-link\"})}),\"Footnotes\"]}),\"\\n\",a(i.p,{children:[\"1 ⢠There's an amazing\\n\",n(i.a,{href:\"https://www.youtube.com/watch?v=k1FdrhA2sCY\",children:\"talk by Evan Bacon on Expo for Web\"}),\"\\nthis year at Reactive Conf â if you haven't checked it out, I really recommend\\nyou to.\"]}),\"\\n\",a(i.p,{children:[\"2 ⢠This one was authored and is the same used by Bruno Lemos, the author of\\n\",n(i.a,{href:\"https://devhubapp.com/\",children:\"DevHub\"}),\", a Github client that runs on Android, iOS,\\nWeb, and Desktop with 95%+ code sharing between them. If you're interested in\\nhow he came up with this solution, check\\n\",n(i.a,{href:\"https://dev.to/brunolemos/tutorial-100-code-sharing-between-ios-android--web-using-react-native-web-andmonorepo-4pej\",children:\"this\"}),\"\\nout.\"]}),\"\\n\",n(i.p,{children:\"3 ⢠These issues include:\"}),\"\\n\",a(i.ul,{children:[\"\\n\",a(i.li,{children:[\"Functionality-wide\",\"\\n\",a(i.ul,{children:[\"\\n\",a(i.li,{children:[\"Query parameters from URL not passed down\\n(\",n(i.a,{href:\"https://github.com/react-navigation/web/issues/45\",children:\"here\"}),\")\"]}),\"\\n\",a(i.li,{children:[\"Pushing back not working\\n(\",n(i.a,{href:\"https://github.com/react-navigation/web/issues/22\",children:\"here\"}),\" and\\n\",n(i.a,{href:\"https://github.com/react-navigation/web/issues/41\",children:\"here\"}),\")\"]}),\"\\n\",n(i.li,{children:\"Some params pushed from one route to the other for convenience being encoded\\nto the URL\"}),\"\\n\"]}),\"\\n\"]}),\"\\n\",a(i.li,{children:[\"Developer-experience-wide\",\"\\n\",a(i.ul,{children:[\"\\n\",a(i.li,{children:[\"Lack of TypeScript typings\\n(\",n(i.a,{href:\"https://github.com/react-navigation/web/issues/34\",children:\"here\"}),\") â which made me\\nwrite part of the definitions on my own\"]}),\"\\n\"]}),\"\\n\"]}),\"\\n\"]}),\"\\n\",a(i.p,{children:[\"4 ⢠\",n(i.a,{href:\"https://reacttraining.com/blog/react-router-v5/\",children:\"React Router v5\"}),\" focused\\nmostly on introducing structural improvements and a few new features. But then\\n\",n(i.a,{href:\"https://reacttraining.com/blog/react-router-v5-1/\",children:\"v5.1\"}),\" brought a bunch of\\nsome useful hooks which allowed us to implement the mentioned ones for the web.\"]}),\"\\n\",a(i.p,{children:[\"5 â¢\\n\",n(i.a,{href:\"https://blog.expo.io/announcing-react-navigation-5-0-bd9e5d45569e\",children:\"React Navigation v5\"}),\"\\nalso did many efforts for bringing a modern, hooks-first API, allowed us to\\nimplement the mentioned ones for mobile.\"]}),\"\\n\",a(i.p,{children:[\"6 ⢠There's a very good post about doing declarative and composable navigation\\nwith \",n(i.co
2de,{children:\"\u003cRedirect /\u003e\"}),\"\\n\",n(i.a,{href:\"https://tylermcginnis.com/react-router-programmatically-navigate/\",children:\"here\"}),\".\"]}),\"\\n\",a(i.p,{children:[\"7 ⢠If you're interested in this topic, in\\n\",n(i.a,{href:\"https://www.ythecombinator.space/talks/code-sharing-at-scale-one-codebase-for-web-mobile-and-desktop\",children:\"this talk\"}),\"\\nI share a couple of lessons learned while building an app with code sharing as a\\nprimary objective â from project setup, through shared infrastructure, all the\\nway up to shared components and styling â and how you can achieve the same\\nthing.\"]})]})}return{default:function(e={}){const{wrapper:a}=e.components||{};return a?n(a,{...e,children:n(_createMdxContent,{...e})}):_createMdxContent(e)}};"},"_tags":["react","react native","navigation"]},{"title":"It's all about trusting the magic of beginnings","date":"2019-07-15T00:00:00.000Z","summary":"After almost two years immersed in countless exciting challenges, it's time to move on.","language":"en","tags":["career","life"],"slug":"it-s-all-about-trusting-the-magic-of-beginnings","hero":"/content/posts/it-s-all-about-trusting-the-magic-of-beginnings/hero.png","readingTime":{"text":"4 min read","minutes":3.09,"time":185400,"words":618},"body":{"code":"const{Fragment:e,jsx:n,jsxs:t}=arguments[0];function _createMdxContent(o){const a={a:\"a\",h2:\"h2\",p:\"p\",span:\"span\",strong:\"strong\",...o.components};return t(e,{children:[n(a.p,{children:\"After almost two years immersed in countless exciting challenges, it's time to\\nmove on.\"}),\"\\n\",t(a.h2,{id:\"my-journey-in-a-nutshell\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#my-journey-in-a-nutshell\",children:n(a.span,{className:\"icon icon-link\"})}),\"My Journey in a Nutshell\"]}),\"\\n\",t(a.p,{children:[\"One of the funniest things, when I started working at\\n\",n(a.a,{href:\"https://beakyn.com\",children:\"Beakyn\"}),\", was realizing that every single piece of code I\\nwrote would run in thousands of computers around America. Up to that moment in\\nmy career, I had only worked on small local startups, where the impact of their\\nproducts had way smaller proportions.\"]}),\"\\n\",t(a.p,{children:[\"At Beakyn, I had the chance to contribute to a couple of projects that impacted\\nthe whole assets inventory management and audience demographic analysis\\nlifecycle of our client, \",n(a.a,{href:\"https://www.outfrontmedia.com\",children:\"Outfront Media\"}),\" â one\\nof the largest outdoor media companies in America.\"]}),\"\\n\",n(a.p,{children:\"It all happened combined with efforts to shape a culture of sharing and\\nopenness, and I'm so proud of the achievements we've made!\"}),\"\\n\",\"\\n\",t(a.p,{children:[\"I also had the opportunity to present\\n\",n(a.a,{href:\"https://www.ythecombinator.space/talks\",children:\"some of the cool things I learned\"}),\"\\nwhile working on our projects in conferences and meetups. This allowed me to\\ngrow my presentation skills (I know there is always a wide room for improvement\\nhere, tho) and to create a great network of contacts among our community.\"]}),\"\\n\",\"\\n\",t(a.p,{children:[\"On the personal side, I feel that I have grown so much! My remote working\\nroutine allowed me not only to travel a lot more through my country â not\\nstaying for too long in any city â but to visit new ones. This made me meet tons\\nof great people, get to know wonderful cultures, experience great things and\\ncapture all of \",n(a.a,{href:\"https://www.instagram.com/ythecombinator\",children:\"these moments\"}),\" in\\nphotos! By the way, it all showed me photography is a strong candidate to become\\nthe hobby I've been constantly looking for \",n(a.span,{role:\"img\",\"aria-label\":\"camera with flash\",children:\"ð¸\"}),\".\"]}),\"\\n\",\"\\n\",t(a.h2,{id:\"the-need-for-a-change\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#the-need-for-a-change\",children:n(a.span,{className:\"icon icon-link\"})}),\"The Need for a Change\"]}),\"\\n\",t(a.p,{children:[\"Earlier this year, though, I caught myself on LinkedIn, casually looking for a\\nnew job, and this made me think that it was time to move on. You know what they\\nsay⦠\",n(a.strong,{children:\"when you're feeling attracted by other opportunities, it's a big sign you\\nneed a change\"}),\". I then applied to some companies and met plenty of great people\\nduring the interviews, but one of them really had me from helloâ¦\"]}),\"\\n\",t(a.h2,{id:\"coming-next\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#coming-next\",children:n(a.span,{className:\"icon icon-link\"})}),\"Coming Next\"]}),\"\\n\",t(a.p,{children:[\"In the coming days, I'll be joining the Front-End division at\\n\",n(a.a,{href:\"https://www.strv.com\",children:\"STRV\"}),\" â a mobile \u0026 web application development company\\nthat supplies start-ups all over the world with applications developed in such\\nprestigious incubators like Y
2Combinator, 500 Startups, and others.\"]}),\"\\n\",n(a.p,{children:\"I must say that I couldn't be more excited about it, but many things need to\\nhappen before I move definitively to the Czech Republic. Meanwhile, I'll be\\nworking remotely.\"}),\"\\n\",n(a.p,{children:\"I'm very enthusiastic about what's coming down the line. I really hope to make\\nan impact on the projects, make countless new friends, and bring the best of me\\nto this company and all of its clients and partners.\"}),\"\\n\",n(a.p,{children:\"Furthermore, I also hope to keep pushing great things to production, attend\\nconferences, open-source stuff and help to grow the React.js (and front-end)\\ncommunity.\"}),\"\\n\",n(a.p,{children:\"For those who made it to the end of this post and are somehow part of this\\njourney, thank you so much for everything. I learned more than ever during this\\ntime. I really appreciate all kinds of learning and experiences you guys\\nprovided to me.\"}),\"\\n\",t(a.p,{children:[\"Wish me luck! \",n(a.span,{role:\"img\",\"aria-label\":\"crossed fingers\",children:\"ð¤\"}),n(a.span,{role:\"img\",\"aria-label\":\"fireworks\",children:\"ð\"})]})]})}return{default:function(e={}){const{wrapper:t}=e.components||{};return t?n(t,{...e,children:n(_createMdxContent,{...e})}):_createMdxContent(e)}};"},"_tags":["career","life"]},{"title":"A Whole Day Playing with IPFS","date":"2017-12-15T00:00:00.000Z","summary":"This is mostly a controversial decentralized web technologies research story but, before starting, there are a few things I'd like to ensure you all, my beloved readers, are aware of.","language":"en","tags":["ipfs","distributed systems"],"slug":"a-whole-day-playing-with-ipfs","hero":"/content/posts/a-whole-day-playing-with-ipfs/hero.png","readingTime":{"text":"10 min read","minutes":9.26,"time":555600,"words":1852},"body":{"code":"const{Fragment:e,jsx:n,jsxs:t}=arguments[0];function _createMdxContent(i){const a={a:\"a\",blockquote:\"blockquote\",code:\"code\",h3:\"h3\",h4:\"h4\",img:\"img\",li:\"li\",p:\"p\",pre:\"pre\",span:\"span\",strong:\"strong\",ul:\"ul\",...i.components};return t(e,{children:[n(a.p,{children:\"This is pretty much a controversial decentralized web technologies research\\nstory but, before starting, there are a few things I'd like to ensure you all,\\nmy beloved readers, are aware of.\"}),\"\\n\",t(a.p,{children:[\"The first one is my original purpose during this first Mad Science Weekend: I\\nwanted to do some research around a few of the main buzz words we have nowadays\\nwhen it comes to decentralized web, focusing on the famous peer-to-peer\\nprotocol: IPFS, making simple examples (PoCs) so that we can evaluate if it is\\nsuitable for usage in one of the Beakynâs applications in order to find a more\\n\",n(a.strong,{children:\"efficient\"}),\", \",n(a.strong,{children:\"cheap\"}),\", and \",n(a.strong,{children:\"reliable\"}),\" way to serve our data.\"]}),\"\\n\",n(a.p,{children:\"Secondly, I have sort of a disclaimer: this post can, sometimes, sound more\\ntechnical than it really is, so don't you feel afraid of any buzz word and ping\\nme if you have any kind of questions or other feedbackâas Juan usually says:\"}),\"\\n\",t(a.blockquote,{children:[\"\\n\",n(a.p,{children:\"âHey stupid! You could do this or thatâ.\"}),\"\\n\"]}),\"\\n\",t(a.h3,{id:\"research-organization\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#research-organization\",children:n(a.span,{className:\"icon icon-link\"})}),\"Research Organization\"]}),\"\\n\",n(a.p,{children:\"The final result of this research is split in three different parts:\"}),\"\\n\",t(a.ul,{children:[\"\\n\",t(a.li,{children:[\"Research Synthesis â Guess what? The post you're reading right now \",n(a.span,{role:\"img\",\"aria-label\":\"see-no-evil monkey\",children:\"ð\"}),\".\"]}),\"\\n\",t(a.li,{children:[\"Sample Publishing Script â This is a simple Node.js script which basically\\nfetches our last \",n(a.code,{children:\".pbf\"}),\" files, encrypts them, and then publishes the data to\\nIPFS. It also contains a few helper functions for encrypting/decrypting data\\nwhich are built on top of \",n(a.a,{href:\"https://nodejs.org/api/crypto.html\",children:\"Crypto\"}),\" and\\n\",n(a.a,{href:\"https://github.com/JoshKaufman/ursa\",children:\"URSA\"}),\".\"]}),\"\\n\",t(a.li,{children:[n(a.code,{children:\"mad-science-weekend\"}),\" branch â I wanted to test all this stuff in a scenario\\nthat is a bit closer to the real world; so I ended up with a branch on one of\\nour systems which fetches.pbf files from IPFS hashes instead of regular AWS\\nendpoints.\"]}),\"\\n\"]}),\"\\n\",t(a.h3,{id:\"impressions\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#impressions\",children:n(a.span,{className:\"icon icon-link\"})}),\"Impressions\"]}),\"\\n\",n(a.p,{children:\"Here go a few of my general impressions when it comes to IPFS/IPNS and other\\nrelated stuff that ended up being part of my studiesâe.g. Data Encryption.\"}),\"\\n\",t(a.h4,{id:\"overview\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#overview\",children:n(a.span,{className:\"icon icon-link\"})}),\"Overview\"]}),\"\\n\",t(a.blockquote,{children:[\"\\n\",t(a.p,{children:[\"If you don't need anything like an IPFS 101, just skip all this section \",n(a.span,{role:\"img\",\"aria-label\":\"smiling face with sunglasses\",children:\"ð\"}),\".\"]}),\"\\n\"]}),\"\\n\",n(a.p,{children:\"In summary, it consists of a peer-to-peer protocol for distributed file systems.\\nThe simplest way to access the content in IPFS is by its public gateway, tough\\nitâs possible to run a daemon locally or host gateway of your own.\"}),\"\\n\",n(a.p,{children:\"After any kind of data, such as a file, is added to IPFS, it then becomes the so\\ncalled objects. Each object has a hash which is generated based on its content\\nand will be available through it.\"}),\"\\n\",n(a.p,{children:\"For example:\"}),\"\\n\",n(a.pre,{className:\"language-sh\",children:t(a.code,{className:\"language-sh code-highlight\",children:[t(a.span,{className:\"code-line\",children:[n(a.span,{className:\"token comment\",children:'# If a text file containing \"hello worlds\" is added to IPFS:'}),\"\\n\"]}),t(a.span,{className:\"code-line\",children:[n(a.span,{className:\"token operator\",children:\"\u003e\"}),\" \",n(a.span,{className:\"token builtin class-name\",children:\"e
2cho\"}),\" \",n(a.span,{className:\"token string\",children:'\"hello worlds\"'}),\" \",n(a.span,{className:\"token operator\",children:\"|\"}),\" ipfs \",n(a.span,{className:\"token function\",children:\"add\"}),\"\\n\"]}),t(a.span,{className:\"code-line\",children:[n(a.span,{className:\"token comment\",children:\"# Then it will be available with the following hash:\"}),\"\\n\"]}),n(a.span,{className:\"code-line\",children:\"added QmZ4tDuvesekSs4qM5ZBKpXiZGun7S2CYtEZRB3DYXkjGx\\n\"}),t(a.span,{className:\"code-line\",children:[n(a.span,{className:\"token operator\",children:\"\u003e\"}),\" ipfs \",n(a.span,{className:\"token function\",children:\"cat\"}),\" QmZ4tDuvesekSs4qM5ZBKpXiZGun7S2CYtEZRB3DYXkjGx\\n\"]}),n(a.span,{className:\"code-line\",children:\"ipfs\\n\"})]})}),\"\\n\",n(a.p,{children:\"All objects contained in IPFS are immutable which means that if itâs necessary\\nto add a new version of a file, a new object will be created, completely\\nregardless of the previous one. Then a brand new hash is obtainedâand the\\nprevious one will still to be available due to its immutable nature.\"}),\"\\n\",n(a.p,{children:\"If the text from the previous example gets changed to IPFS, weâre going to have\\na new hash representing it:\"}),\"\\n\",n(a.p,{children:n(a.code,{children:\"QmbXBAKDgbhE8HkGuEF4FuQQJej2mxqXtYSMsBPuJDqgjq\"})}),\"\\n\",n(a.p,{children:\"This happens due to the concept of Content Addressable Storage which is strongly\\npresent in IPFS. That is, the data in IPFS is addressed by one hash generated\\nfrom its content, ensuring:\"}),\"\\n\",t(a.ul,{children:[\"\\n\",t(a.li,{children:[\"More \",n(a.strong,{children:\"integrity\"}),\", regardless of where or who offers the content.\"]}),\"\\n\",t(a.li,{children:[\"That the links are \",n(a.strong,{children:\"permanent\"}),\"; always pointing to same object.\"]}),\"\\n\"]}),\"\\n\",t(a.h4,{id:\"latency\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#latency\",children:n(a.span,{className:\"icon icon-link\"})}),\"Latency\"]}),\"\\n\",t(a.blockquote,{children:[\"\\n\",t(a.p,{children:[n(a.strong,{children:\"tl;dr\"}),\": Negative.\"]}),\"\\n\"]}),\"\\n\",n(a.p,{children:\"Although the concept of content-addressing brings a bunch of benefits, initially\\nitâd become unsuitable for cases where itâs necessary to constantly get the last\\nversion of something, since itâd need to get the hash of last version of the\\nobject in another channel.\"}),\"\\n\",t(a.p,{children:[\"To solve this problem another protocol, called IPNS, was developed. With the\\n\",n(a.code,{children:\"peerId\"}),\", the hash of the user's public key, it then became possible to create a\\nredirect to a specific object. So, for didactic purposes, you may want to\\nunderstand IPNS as a small amount of mutability to the permanent immutability\\nthat is IPFS, since it allows you to store a reference to a hash and update what\\nthat reference points to by simply executing a publish command.\"]}),\"\\n\",t(a.blockquote,{children:[\"\\n\",t(a.p,{children:[n(a.strong,{children:\"Intermission\"}),\": Itâs important to emphasize this due to the fact that the\\ncontent on the platform I'm using on this PoC is synchronized with data from\\nother platform of ours every day at a set time. This means that every day a\\nbot on Amazon Elastic Compute Cloud (AWS EC2) reads the data from one our\\nMongoDB instances and then generates a few \",n(a.code,{children:\".pbf\"}),\" files which are then served\\nvia the Amazon Simple Storage Service (AWS S3).\"]}),\"\\n\"]}),\"\\n\",t(a.h4,{id:\"resilience\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#resilience\",children:n(a.span,{className:\"icon icon-link\"})}),\"Resilience\"]}),\"\\n\",t(a.blockquote,{children:[\"\\n\",t(a.p,{children:[n(a.strong,{children:\"tl;dr\"}),\": Positive.\"]}),\"\\n\"]}),\"\\n\",n(a.p,{children:\"Something at least interesting when it comes to the IPNS usage is the name\\navailability time. Whenever the bot running on the AWS EC2 instance adds a new\\nobject to IPFS and creates a redirect of its IPNS hash to the new object, it can\\nthen shutdown the daemon in its computer. The IPFS nodeâwhich includes the\\npublic gateway oneâ, will keep holding the IPNS address using a cache system.\"}),\"\\n\",n(a.p,{children:'In other words, we do know that someone needs to resolve the IPNS address. We\\nalso know that this guy, in general, is the owner of IPFS hash that says \"Hey,\\nmy IPNS hash points to that object over there\". However, the IPFS network also\\ncaches the resolution of that name, so then if the node is down, that IPNS hash\\nis still resolvableâwhich, by the way, has a lifetime of up to 36 hours.'}),\"\\n\",t(a.p,{children:[\"For our context, since there is always an active instance which publishes the\\ndata in IPFS, we generally donât have to worry about the expiration of IPNS\\nresolution. Since the data changes every \",n(a.code,{children:\"24h\"}),\", and the lifetime is \",n(a.code,{children:\"36h\"}),\", even\\nif we faced downtime, the resolution would still be available.\"]}),\"\\n\",t(a.p,{children:[\"This may represent a gain in resilience since none of the experienced service\\ndisruptions would affect the availability of the \",n(a.code,{children:\".pbf\"}),\" data.\"]}),\"\\n\",t(a.h4,{id:\"sensitive-data\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#sensitive-data\",children:n(a.span,{className:\"icon icon-link\"})}),\"Sensitive Data\"]}),\"\\n\",t(a.blockquote,{children:[\"\\n\",t(a.p,{children:[n(a.strong,{children:\"tl;dr\"}),\": \",n(a.strong,{children:\"DEFINITELY\"}),\" Needs more research.\"]}),\"\\n\"]}),\"\\n\",t(a.p,{children:[\"Due to the very sensitive nature of the data our \",n(a.code,{children:\".pbf\"}),\"s hold, it turns out to\\nbe necessary to find a way of ensuring that this data is only accessible to our\\ntrusted clients.\"]}),\"\\n\",n(a.p,{children:\"Since there seem to be many alternativesâand given the time constraintsâ, it was\\nhard for me to choose between one of them.\"}),\"\\n\",n(a.p,{children:\"When it comes to IPFS itself, SWARM filters at first sight seemed to be a good\\nalternative but it was still unclear to me how experimental they were. Also, I\\nthought about private networksâwhich enforce connection to only peers who have a\\nshared secret keyâbut it is documented as still experimental, too.\"}),\"\\n\",t(a.p,{children:[\"Other alternativesâwhich are actually kind of alternatives to IPFS itselfâare\\nthe ones designed focused on private usageâe.g.\\n\",n(a.a,{href:\"https://github.com/Peergos/Peergos\",children:\"Peergos\"}),\" and\\n\",n(a.a,{href:\"https://camlistore.org/\",children:\"Camlistore\"}),\".\"]}),\"\\n\",n(a.p,{children:\"For this PoC, the chosen approach was encrypting files before adding them to\\nIPFSâyeah, I know at first sight it seems to be a naive choice, but the IPFS\\ncreator, Juan Benet, has already mentioned he used this strategy for his\\npersonal files.\"}),\"\\n\",t(a.p,{children:[\"Although we use a few good optimization techniquesâe.g. this\\n\",n(a.a,{href:\"https://github.com/mapbox/pbf\",children:\"lightweight Protobuf\"}),\" implementation and the\\n\",n(a.a,{href:\"https://github.com/google/brotli\",children:\"Brotli\"}),\" compression algorithmâthe amount of\\ndata we have to encryptâabout 8 \",n(a.code,{children:\".pbf\"}),\" files which hold geodata from thousands\\nof Points Of Interest (POIs)âis still considered large data depending on the\\nsize of the RSA generated key due to this\\n\",n(a.a,{href:\"https://github.com/JoshKaufman/ursa/issues/14\",children:\"issue\"}),\" on\\n\",n(a.a,{href:\"https://github.com/JoshKaufman/ursa\",children:\"URSA\"}),\".\"]}),\"\\n\",t(a.p,{children:[\"As it can be seen in the figure below, in an experiment during this PoC, a\\n\",n(a.code,{children:\"2^13\"}),\" bytes-sized RSA key wasn't able to encrypt even one of our \",n(a.code,{children:\"8\"}),\" geodata\\nchunks using URSAâwhich is, by the way, one of the most used OpenSSL bindings\\nfor Node.js.\"]}),\"\\n\",n(a.p,{children:n(a.img,{src:\"/content/posts/a-whole-day-playing-with-ipfs/data-too-large.png\",alt:\"Data too large\"})}),\"\\n\",t(a.blockquote,{children:[\"\\n\",n(a.p,{children:\"The used RSA key was generated using genrsa from OpenSSL 0.9.8 running on\\ndarwin64-x86_64-llvm inside a MacBook Pro (8 GB 1867 MHz DDR3 | 2,7 GHz Intel\\nCore i5).\"}),\"\\n\"]}),\"\\n\",t(a.p,{children:[\"Given those limitations, I came up with symmetric cipher based approach, using a\\nsimple AES 256-based encryption that comes\\n\",n(a.a,{href:\"https://nodejs.org/api/crypto.html\",children:\"built-in with Node.js\"}),\".\"]}),\"\\n\",t(a.h3,{id:\"at-the-end-of-the-day\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#at-the-end-of-the-day\",children:n(a.span,{className:\"icon icon-link\"})}),\"At The End of The Dayâ¦\"]}),\"\\n\",t(a.p,{children:[\"⦠I noticed I had a lot of fun \",n(a.span,{role:\"img\",\"aria-label\":\"TOP arrow\",children:\"ð\"}),n(a.span,{role:\"img\",\"aria-label\":\"rainbow\",children:\"ð\"}),n(a.span,{role:\"img\",\"aria-label\":\"glowing star\",children:\"ð\"}),n(a.span,{role:\"img\",\"aria-label\":\"sparkler\",children:\"ð\"}
2),n(a.span,{role:\"img\",\"aria-label\":\"fireworks\",children:\"ð\"}),\".\"]}),\"\\n\",t(a.p,{children:[\"I kinda see that there are probably many good cases here at Beakyn where IPFS\\ncould be a nice playerâeven this blog could be built on top of itâbut, as of\\nnow, and given the fact that this was just a short weekend researchâso don't\\nlook at me as the decentralized web guruâ, I think that, for the specific case\\ndescribed during the post, everything considered, it's not suitable, mainly\\nbecause of the extra layers of concerns it seemed to add when it comes to\\n\",n(a.strong,{children:\"latency\"}),\" and \",n(a.strong,{children:\"sensitive data security\"}),\".\"]}),\"\\n\",t(a.p,{children:[\"Last but not least, a very special thanks goes to both\\n\",n(a.a,{href:\"https://github.com/macabeus\",children:\"Bruno\"}),\" and\\n\",n(a.a,{href:\"https://github.com/marcsvll\",children:\"Marcus\"}),\"âtwo friends of mineâfor being so attentive\\nto all my doubts and always being available for long conversations involving\\ndecentralized web stuff.\"]}),\"\\n\",t(a.h3,{id:\"things-i-would-like-to-have-studied-more\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#things-i-would-like-to-have-studied-more\",children:n(a.span,{className:\"icon icon-link\"})}),\"Things I Would Like to Have Studied More\"]}),\"\\n\",n(a.p,{children:\"These are a few subjects/technologies Iâd like to have read more aboutâand which\\neach would result in a different Mad Science Weekend:\"}),\"\\n\",n(a.p,{children:\"IPNS â I do believe that better understanding naming resolution under-the-hood\\nwould help me being able to collaborate on the latency issue solving, or at\\nleast understand its roots.\"}),\"\\n\",t(a.p,{children:[n(a.a,{href:\"https://github.com/Peergos/Peergos\",children:\"Peergos\"}),\" â As a peer-to-peer encrypted\\nfilesystemâbuilt on the top of IPFSâ, at first sight, it seemed to me like a\\nsolution closer to what weâre looking for given its private sharing design goal.\"]}),\"\\n\",t(a.p,{children:[n(a.a,{href:\"https://camlistore.org/\",children:\"Camlistore\"}),\" â Again, given my superficial impressions,\\nit seemed to me like a solution closer to what weâre looking for.\"]}),\"\\n\",t(a.p,{children:[n(a.a,{href:\"https://github.com/y-js/yjs\",children:\"Y.js\"}),\" â Offline-first p2p shared editing would be\\nsomething amazing to have on the other systems of oursâe.g. something that\\nevolves map data creation.\"]}),\"\\n\",t(a.p,{children:[n(a.a,{href:\"https://github.com/orbitdb/orbit-db\",children:\"OrbitDB\"}),\" â Given its key-Value store\\nnature, it could be a good MongoDB replacement in a scenario where we migrate\\nour stack to a decentralized one.\"]}),\"\\n\",t(a.h3,{id:\"references--further-reading\",children:[n(a.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#references--further-reading\",children:n(a.span,{className:\"icon icon-link\"})}),\"References \u0026 Further Reading\"]}),\"\\n\",t(a.ul,{children:[\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"Amazon Web Services Reports. (2017).\\n\",n(a.a,{href:\"https://aws.amazon.com/pt/message/41926/\",children:\"Summary of the Amazon S3 Service Disruption in the Northern Virginia (US-EAST-1) Region\"}),\".\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"Benet, J. (2015).\\n\",n(a.a,{href:\"https://github.com/ipfs/papers/blob/master/ipfs-cap2pfs/ipfs-p2p-file-system.pdf\",children:\"IPFSâââContent Addressed, Versioned, P2P File System\"}),\".\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",n(a.p,{children:\"Dave Longley (2013). [Failed to encrypt buffer with length 256 with 2048 bit\\nRSA · Issue #14]( Failed to encrypt buffer with length 256 with 2048 bit RSA ·\\nIssue #14).\"}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",n(a.p,{children:\"Hartmann, C. (2014). [Encrypt and decrypt content with Nodejs](Encrypt and\\ndecrypt content with Nodejs.).\"}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"IPFS (2016).\\n\",n(a.a,{href:\"https://github.com/i
2pfs/faq/issues/154\",children:\"Questions after first learning about IPFS · Issue #154\"}),\".\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"IPFS (2016).\\n\",n(a.a,{href:\"https://github.com/ipfs/faq/issues/181\",children:\"Is it possible to store private objects in ipfs without encrypting them? · Issue #181\"}),\".\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"IPFS (2016).\\n\",n(a.a,{href:\"https://github.com/ipfs/faq/issues/4\",children:\"Private/personal use of ipfs? · Issue #4\"}),\".\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"IPFS (2016).\\n\",n(a.a,{href:\"https://github.com/ipfs/go-ipfs/issues/3866\",children:\"Keystore/encryption/ipfs usecase for a file-sharing application · Issue #3866\"}),\".\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"Macabeus, B. (2017).\\n\",n(a.a,{href:\"http://macalogs.com.br/prova-de-conceito-protocolos-ipfs-e-ipns-como-meio-para-o-controle-de-botnet.html\",children:\"IPFSâ âandâ âIPNSâ âprotocolsâ âasâ âwayâ âforâ âcontrollerâ âofâ âbotnet:â âaâ âproof ofâ âconcept\"}),\".\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"Mutunhire, T. (2017).\\n\",n(a.a,{href:\"http://stackabuse.com/writing-to-files-in-node-js/\",children:\"Writing to Files in Node.js\"}),\".\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"OrbitDB (2017). \",n(a.a,{href:\"https://github.com/orbitdb/orbit\",children:\"orbitdb/orbit\"}),\".\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"Reed, J. (2017).\\n\",n(a.a,{href:\"https://discuss.ipfs.io/t/privacy-and-anonymity-in-ipfs-ipns/1068/4\",children:\"Privacy and anonymity in IPFS/IPNS\"}),\".\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"The Golem Project. (2016).\\n\",n(a.a,{href:\"https://golem.network/doc/Golemwhitepaper.pdf\",children:\"The Golem Project Crowdfunding Whitepaper\"}),\".\"]}),\"\\n\"]}),\"\\n\",t(a.li,{children:[\"\\n\",t(a.p,{children:[\"Zumwalt, M., Johnson, J., Benet, J., Gierth, L. and Fisher, L. (2017).\\n\",n(a.a,{href:\"https://www.gitbook.com/book/flyingzumwalt/decentralized-web-primer/details\",children:\"The Decentralized Web Primer\"}),\".\"]}),\"\\n\"]}),\"\\n\"]})]})}return{default:function(e={}){const{wrapper:t}=e.components||{};return t?n(t,{...e,children:n(_createMdxContent,{...e})}):_createMdxContent(e)}};"},"_tags":["ipfs","distributed systems"]},{"title":"Swift In The Sky With Types","date":"2016-03-28T00:00:00.000Z","summary":"... Ou apenas mais uma conversa sobre linguagens, compiladores, tipos e... Swift!","language":"pt","tags":["swift","type systems"],"slug":"swift-in-the-sky-with-types","hero":"/content/posts/swift-in-the-sky-with-types/hero.png","readingTime":{"text":"18 min read","minutes":17.43,"time":1045800,"words":3486},"body":{"code":"const{Fragment:e,jsx:a,jsxs:n}=arguments[0];function _createMdxContent(s){const o={a:\"a\",blockquote:\"blockquote\",code:\"code\",em:\"em\",h2:\"h2\",h3:\"h3\",img:\"img\",li:\"li\",ol:\"ol\",p:\"p\",pre:\"pre\",span:\"span\",strong:\"strong\",ul:\"ul\",...s.components};return n(e,{children:[n(o.blockquote,{children:[\"\\n\",n(o.p,{children:[\"Originally published\\n\",a(o.a,{href:\"http://equinocios.com/swift/2016/03/28/swift-in-the-sky-with-types/\",children:\"here\"}),\".\\nIt'll be soon translated into English, I promise \",a(o.span,{role:\"img\",\"aria-label\":\"grinning face with smiling eyes\",children:\"ð\"}),\".\"]}),\"\\n\"]}),\"\\n\",a(o.p,{children:\"Antes de tudo, algumas coisas a se levar em consideração:\"}),\"\\n\",n(o.ol,{children:[\"\\n\",n(o.li,{children:[\"\\n\",n(o.p,{children:[\"Esse post é baseado em experiências - e eu não sou nenhum tipo de \",a(o.em,{children:\"dono da\\nverdade\"}),\": se você tem alguma opinião sobre isso - concordando, discordando,\\ncomplementando -, sinta-se livre para compartilhá-la.\"]}),\"\\n\"]}),\"\\n\",n(o.li,{children:[\"\\n\",a(o.p,{children:\"Nem tudo nesse post é sobre Swift: boa parte dele está relacionada a\\nexperiências bem gerais relacionadas a projeto de linguagens de programação.\"}),\"\\n\"]}),\"\\n\",n(o.li,{children:[\"\\n\",n(o.p,{children:[\"Há boatos que a experiência de ler o post é enriquecida ouvindo-se o álbum\\n\",a(o.a,{href:\"https://play.spotify.com/album/6QaVfG1pHYl1z15ZxkvVDW\",children:\"Sgt. Pepper's Lonely Hearts Club Band\"}),\"\\n\",a(o.span,{role:\"img\",\"aria-label\":\"smiling face\",children:\"âºï¸\"}),\".\"]}),\"\\n\"]}),\"\\n\"]}),\"\\n\",n(o.h2,{id:\"prólogo\",children:[a(o.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#prólogo\",children:a(o.span,{className:\"icon icon-link\"})}),\"Prólogo\"]}),\"\\n\",n(o.blockquote,{children:[\"\\n\",n(o.p,{children:[\"Algumas coisas que me levaram a pensar sobre \",a(o.em,{children:\"Sistemas de Tipos\"}),\" - e a\\nescrever esse post...\"]}),\"\\n\"]}),\"\\n\",n(o.p,{children:[\"Eu, \",a(o.a,{href:\"https://github.com/ythecombinator\",children:\"Matheus\"}),\", sou originalmente\\ndesenvolvedor JavaScript. E, como em outras linguagens, tenho de lidar com\\nalguns \",a(o.em,{children:\"probleminhas\"}),\". Por exemplo, sua tipagem dinâmica pode ser problemática:\\nJavaScript não sabe que tipo uma variável é até que esta seja realmente\\n
2atribuÃda em execução - o que significa que pode ser tarde demais, uma vez que\\nvocê não sabe se algum erro de tipo estava em seu código e quebrou antes de\\nexecutá-lo.\"]}),\"\\n\",n(o.p,{children:[\"Além disso, nós não podemos contar com caras como o \",a(o.code,{children:\"instanceof\"}),\" e o \",a(o.code,{children:\"typeof\"}),\":\\neles não funcionam de forma consistente - o que acaba nos mostrando que\\nverificação de tipos em JavaScript é um problema - e você provavelmente tem que\\nfazer alguns \",a(o.em,{children:\"workarounds\"}),\" para ajudar você a superar tal inconsistência - ou\\nusar caras como o \",a(o.a,{href:\"http://www.typescriptlang.org/\",children:\"TypeScript\"}),\" ou o\\n\",a(o.a,{href:\"http://flowtype.org/\",children:\"Flow\"}),\".\"]}),\"\\n\",n(o.p,{children:[\"O que tudo isso tem a ver com Swift? Bem, o contato com algumas inconsistências\\nrelacionadas a tipos presenciadas em algumas linguagens - bem como sistemas de\\ntipos exemplares que pude experimentar em linguagens como\\n\",a(o.a,{href:\"https://www.haskell.org/\",children:\"Haskell\"}),\", \",a(o.a,{href:\"https://ocaml.org/\",children:\"OCaml\"}),\" e\\n\",a(o.a,{href:\"http://fsharp.org/\",children:\"F#\"}),\"- me fez ter sempre tal tópico em mente ao começar em\\numa linguagem - e, há alguns meses, quando comecei a estudar a linguagem da\\nApple, não foi diferente.\"]}),\"\\n\",n(o.h2,{id:\"mas-antes\",children:[a(o.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#mas-antes\",children:a(o.span,{className:\"icon icon-link\"})}),\"Mas Antes...\"]}),\"\\n\",n(o.p,{children:[\"... de começarmos a ver coisas especÃficas de Swift relacionadas a seu sistema\\nde tipos, penso que seja interessante fazermos um \",a(o.em,{children:\"apanhado\"}),' de alguns conceitos\\nmais \"gerais\".']}),\"\\n\",n(o.h3,{id:\"dados\",children:[a(o.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#dados\",children:a(o.span,{className:\"icon icon-link\"})}),\"Dados?\"]}),\"\\n\",a(o.p,{children:a(o.img,{src:\"/content/posts/swift-in-the-sky-with-types/data.png\",alt:\"Dados?\"})}),\"\\n\",n(o.p,{children:[\"Esse é um conceito bem primitivo - e que muitas vezes não é discutido e só\\naceito. Na \",a(o.em,{children:\"Filosofia\"}),\", temos uma definição parecida com isso:\"]}),\"\\n\",n(o.blockquote,{children:[\"\\n\",n(o.p,{children:[\"Coisas conhecidas ou assumidas como \",a(o.em,{children:\"fatos\"}),\", tornando-se a \",a(o.em,{children:\"base do raciocÃnio\\nou cálculo\"}),\".\"]}),\"\\n\"]}),\"\\n\",n(o.p,{children:[\"Ao adentrarmos na \",a(o.em,{children:\"Computação\"}),\", começamos a pensar de uma forma ou pouco\\ndiferente sobre \",a(o.em,{children:\"dados\"}),\" - ou melhor dizendo: um pouco mais \",a(o.em,{children:\"especÃfica\"}),\" para o\\ncontexto em que estamos - e encontramos definições como:\"]}),\"\\n\",n(o.blockquote,{children:[\"\\n\",n(o.p,{children:[a(o.em,{children:\"Quantidades\"}),\", \",a(o.em,{children:\"caracteres\"}),\" ou \",a(o.em,{children:\"sÃmbolos\"}),\" dos quais operações são executadas\\npor um computador, sendo armazenados e transmitidos na forma de sinais\\neléctricos e gravados no suporte de gravação magnética, óptica ou mecânica.\"]}),\"\\n\"]}),\"\\n\",n(o.p,{children:[\"E assim, começamos a pensar mais sobre dados como sendo um determinado pedaço de\\ninformação - \",a(o.em,{children:\"textos\"}),\", \",a(o.em,{children:\"números\"}),\", \",a(o.em,{children:\"listas\"}),\", \",a(o.em,{children:\"figuras\"}),\" etc.: são todos pedaços de\\ninformação.\"]}),\"\\n\",n(o.p,{children:[\"E, como podemos ler no famigerado\\n\",a(o.a,{href:\"https://mitpress.mit.edu/sicp/full-text/book/book.html\",children:a(o.em,{children:\"Livro do Mago\"})}),\":\"]}),\"\\n\",n(o.blockquote,{children:[\"\\n\",n(o.p,{children:[\"[...] \",a(o.em,{children:\"Processos computacionais\"}),\" são seres abstratos que habitam computadores.\\nà medida que evoluem, os processos manipulam outros seres abstratos chamados\\n\",a(o.strong,{children:\"dados\"}),\". A evolução de um processo é dirigida por um padrão de regras\\nchamado \",a(o.em,{children:\"programa\"}),\". As pessoas criam programas para direcionar processos.\\n[...]\"]}),\"\\n\"]}),\"\\n\",a(o.p,{children:\"Dados são uma das partes mais importantes da arte de programar.\"}),\"\\n\",n(o.p,{children:[\"E, particularmente, eu diria que a conversa começa a ficar mais legal quando\\npensamos sobre como essas
2informações são passadas a um computador - afinal,\\neles não sabem o que um \",a(o.em,{children:\"número\"}),\" é, ou o que o \",a(o.em,{children:\"infográfico de seu documento\"}),\" é,\\nou o que a \",a(o.em,{children:\"URL\"}),\" da sua página é - e assim por diante.\"]}),\"\\n\",n(o.p,{children:[\"Então chegamos a - já esperada - conclusão de que, se queremos passar a nosso\\ncomputador qualquer um desses \",a(o.em,{children:\"pedaços de informação\"}),\", precisamos saber\\nrepresentá-los de alguma maneira que o computador entenda.\"]}),\"\\n\",n(o.p,{children:[\"Guarda bem essa palavra: \",a(o.strong,{children:\"representação\"}),\" - pois ela nos leva ao próximo\\ntópico.\"]}),\"\\n\",n(o.h3,{id:\"tipos-de-dados\",children:[a(o.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#tipos-de-dados\",children:a(o.span,{className:\"icon icon-link\"})}),\"Tipos de Dados?\"]}),\"\\n\",a(o.p,{children:a(o.img,{src:\"/content/posts/swift-in-the-sky-with-types/data-types.png\",alt:\"Tipos de Dados?\"})}),\"\\n\",n(o.blockquote,{children:[\"\\n\",n(o.p,{children:[a(o.strong,{children:\"tl;dr\"}),\": Uma representação especÃfica de algum(ns) dado(s).\"]}),\"\\n\"]}),\"\\n\",n(o.p,{children:[\"Basicamente, essa galera aqui te diz como interagir com um determinado \",a(o.em,{children:\"pedaço\\nde informação\"}),\" e ainda pode dizer como essa informação (dado) é representada por\\nmeio de outras informações mais primitivas - ou \",a(o.em,{children:\"vice-versa\"}),\": como interpretar\\ndados mais primitivos a partir de um determinado tipo de dados.\"]}),\"\\n\",n(o.p,{children:[\"Se o ato de programar consiste em gerenciar processos de tal forma que eles\\npossam manipular dados, \",a(o.strong,{children:\"é de importância crucial que tais processos manipulem\\ndados de forma eficiente e correta\"}),\".\"]}),\"\\n\",n(o.p,{children:[\"Seguindo o raciocÃnio, modelar dados de forma que estes possam ser \",a(o.em,{children:\"manipulados\\nde forma eficiente e correta\"}),\" é uma parte essencial de todas as tarefas de um\\nprogramador - e os tipos de dados são essenciais para tal modelagem - assim,\\ntemos neles a \",a(o.strong,{children:\"importantÃssima\"}),\" tarefa de garantir que as interações com um\\ndeterminado \",a(o.em,{children:\"pedaço de informação\"}),\" estejam sempre corretas.\"]}),\"\\n\",n(o.p,{children:[\"A propósito, guarde bem, também, essa palavra: \",a(o.strong,{children:\"correto\"}),\" - pois ela ainda será\\nbem discutida mais a frente.\"]}),\"\\n\",n(o.h3,{id:\"sistemas-de-tipos\",children:[a(o.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#sistemas-de-tipos\",children:a(o.span,{className:\"icon icon-link\"})}),\"Sistemas de Tipos?\"]}),\"\\n\",a(o.p,{children:a(o.img,{src:\"/content/posts/swift-in-the-sky-with-types/type-system.png\",alt:\"Sistemas de Tipos?\"})}),\"\\n\",n(o.blockquote,{children:[\"\\n\",n(o.p,{children:[a(o.strong,{children:\"tl;dr\"}),\": Sistemas do tipo são, em sua essência, estruturas de análise de\\nprogramas.\"]}),\"\\n\"]}),\"\\n\",n(o.p,{children:[\"Soa confuso? Ã, realmente pode ser \",a(o.em,{children:\"bem\"}),\" confuso.\"]}),\"\\n\",a(o.p,{children:\"Que tal pedirmos ajuda aos universitários?\"}),\"\\n\",n(o.p,{children:[\"Bem, \",a(o.a,{href:\"http://www.cis.upenn.edu/~bcpierce/\",children:\"Benjamin Pierce\"}),\", em seu livro\\n\",a(o.a,{href:\"https://www.cis.upenn.edu/~bcpierce/tapl/\",children:\"Types and Programming Languages\"}),\",\\nnos conta que:\"]}),\"\\n\",n(o.blockquote,{children:[\"\\n\",n(o.p,{children:[\"Um sistema de tipos é um método sintático tratável para provar o não\\ncumprimento de certos comportamentos do programa através da classificação de\\n\",a(o.em,{children:\"expressões\"}),\" de acordo com os tipos de valores que estas computam.\"]}),\"\\n\"]}),\"\\n\",a(o.p,{children:\"Eu diria que uma das chaves para entendermos o tópico é o trecho:\"}),\"\\n\",n(o.blockquote,{children:[\"\\n\",a(o.p,{children:\"[...] provar o não cumprimento de certos comportamentos do programa [...].\"}),\"\\n\"]}),\"\\n\",a(o.p,{children:\"a partir do qual podemos ver que, para todo sistema de tipos especÃfico, haverá\\numa lista de coisas que este visa a provar - do que exatamente consiste tal\\nprova é deixado em aberto.\"}),\"\\n\",n(o.p,{children:[\"Uma forma prática de tentar enxergar isso é pensar em simples expressões. Por\\nexemplo, uma vez que o verificador de tipos pega a expressão \",a(o.code,{children:\"1 + 2\"}),', este pode\\n\"olhar\" para o ',a(o.code,{children:\"1\"}),\" e inferir que se trata de um inteiro, olhar para o \",a(o.code,{children:\"2\"}),\" - e\\ntambém inferir que este é um inteiro - e, em seguida, olhar para o operador \",a(o.code,{children:\"+\"}),\",\\ne saber que, quando \",a(o.code,{children:\"+\"}),\" é aplicada a dois inteiros, o resultado é um número\\ninteiro - e aà temos nossa prova.\"]}),\"\\n\",n(o.h3,{id:\"correctness-by-design\",children:[a(o.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#correctness-by-design\",children:a(o.span,{className:\"icon icon-link\"})}),a(o.em,{children:\"Correctness-by-Design\"})]}),\"\\n\",a(o.p,{children:a(o.img,{src:\"/content/posts/swift-in-the-sky-with-types/correctness-by-design.png\",alt:\"Correctness-by-Design\"})}),\"\\n\",a(o.p,{children:\"Esse conceito aqui também é sempre legal de se pensar sobre, garanto.\"}),\"\\n\",n(o.p,{children:[\"Um dos principais objetivos de uma linguagem de programação deve ser a\\ncapacidade de orientar o programador a uma abordagem de \",a(o.em,{children:\"Correctness-by-Design\"}),\".\\nIsto é, um programa que é válido nesta linguagem, também deve ser um programa\\nque funciona como o esperado - ou seja: o sistema simplesmente não poderá chegar\\na um estado inválido; um estado que não cumpre os requisitos de tal programa.\"]}),\"\\n\",a(o.p,{children:\"Para tanto, a linguagem deve fazer um esforço de rejeitar programas que possam\\nestar errados - ou, ao menos, torná-los mais difÃceis de escrever. Assim, você\\nliteralmente não pode escrever código incorreto pelo simples fato de o\\ncompilador não deixar.\"}),\"\\n\",n(o.h3,{id:\"correctness-by-design--sistemas-de-tipos\",children:[a(o.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#correctness-by-design--sistemas-de-tipos\",children:a(o.span,{className:\"icon icon-link\"})}),a(o.em,{children:\"Correctness-by-Design\"}),\" \u0026 Sistemas de Tipos\"]}),\"\\n\",a(o.p,{children:a(o.img,{src:\"/content/posts/swift-in-the-sky-with-types/correctness-by-design-and-type-systems.png\",alt:\"Correctness-by-Design \u0026 Sistemas de Tipos\"})}),\"\\n\",a(o.p,{children:\"Agora que já temos uma ideia geral em torno de sistemas de tipos e de como\\nlinguagens devem ser projetadas de modo a naturalmente evitar que programas\\nfeitos nestas atinjam estados inválidos, você deve estar se perguntando: qual é\\na exata relação entre ambos?\"}),\"\\n\",n(o.p,{children:[\"Sinceramente, eu gostaria de ter uma relação própria já estabelecida tão\\nexpressiva quanto a feita pelo ilustre pesquisador\\n\",a(o.a,{href:\"http://lucacardelli.name/\",children:\"Luca Cardelli\"}
2),\", da\\n\",a(o.a,{href:\"http://research.microsoft.com/en-us/default.aspx\",children:\"Microsoft Research\"}),\":\"]}),\"\\n\",n(o.blockquote,{children:[\"\\n\",n(o.p,{children:[\"O propósito fundamental de um sistema de tipo é \",a(o.strong,{children:\"evitar a ocorrência de erros\\ndurante a execução de um programa\"}),\".\"]}),\"\\n\"]}),\"\\n\",a(o.p,{children:\"Ainda subjetivo? Ele vai além:\"}),\"\\n\",n(o.blockquote,{children:[\"\\n\",n(o.p,{children:[\"Sistemas de tipos fornecem ferramentas conceituais para julgar a adequação de\\naspectos importantes de definições da linguagem. Descrições de linguagem\\ninformais muitas vezes não conseguem especificar a estrutura de tipos de uma\\nlinguagem com detalhes suficientes de maneira a evitar a aplicação equÃvoca.\\nMuitas vezes, acontece que diferentes compiladores para a mesma linguagem\\nimplementam sistemas de tipo ligeiramente diferentes. Além disso, muitas\\ndefinições de linguagens se mostraram ser defeituosas no quesito tipos,\\npermitindo que um programa quebre - mesmo sendo considerado aceitável por um\\n\",a(o.em,{children:\"typechecker\"}),\".\"]}),\"\\n\"]}),\"\\n\",n(o.p,{children:[\"Assim, vemos no nosso sistema de tipos a figura responsável por \",a(o.em,{children:'\"julgar a\\nadequação de aspectos importantes das definições de uma linguagem\"'}),\", de forma a\\n\",a(o.em,{children:'\"evitar a escrita de código incorreto pelo simples fato de o compilador não\\ndeixar\"'}),\".\"]}),\"\\n\",n(o.h3,{id:\"o-que-temos-por-aÃ\",children:[a(o.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#o-que-temos-por-aÃ\",children:a(o.span,{className:\"icon icon-link\"})}),\"O Que Temos Por AÃ?\"]}),\"\\n\",a(o.p,{children:a(o.img,{src:\"/content/posts/swift-in-the-sky-with-types/what-we-have.png\",alt:\"O Que Temos Por AÃ?\"})}),\"\\n\",a(o.p,{children:\"Esta seção serve mais para contextualizar Swift entre outras linguagens antes de\\nfalarmos especificamente desta.\"}),\"\\n\",n(o.p,{children:[\"As linguagens se dividem em duas categorias: \",a(o.strong,{children:\"tipadas\"}),\" e \",a(o.strong,{children:\"não-tipadas\"}),\" - ou\\n\",a(o.em,{children:\"unitipadas\"}),\".\"]}),\"\\n\",n(o.blockquote,{children:[\"\\n\",n(o.p,{children:[a(o.em,{children:\"Bônus\"}),\": Até a forma como pensamos na definição de tipos pode variar dentro\\ndesse espectro, mas isso é tema para outras discussões - e vamos manter a\\nnossa definição alcançada nas seções anteriores.\"]}),\"\\n\"]}),\"\\n\",n(o.p,{children:[\"Na primeira, temos representantes como \",a(o.em,{children:\"Haskell\"}),\", \",a(o.em,{children:\"OCaml\"}),\", \",a(o.em,{children:\"F#\"}),\", entre muitas\\noutras, incluindo nossa querida \",a(o.em,{children:\"Swift\"}),\". Nestas, as expressões têm tipos\\ndiferentes, e quando se combina uma expressão particular, os tipos devem estar\\ncoerentes - assim, se você tem uma expressão \",a(o.code,{children:\"Int\"}),\" + \",a(o.code,{children:\"Int\"}),\", não é possÃvel\\nescrever \",a(o.code,{children:'\"Swift\"'}),\" + \",a(o.code,{children:\"1\"}),\", porque \",a(o.code,{children:'\"Swift\"'}),\" não tem o tipo \",a(o.code,{children:\"Int\"}),\".\"]}),\"\\n\",n(o.p,{children:[\"Na segunda, também temos representantes de peso, como: \",a(o.em,{children:\"Clojure\"}),\", \",a(o.em,{children:\"Erlang\"}),\" e\\n\",a(o.em,{children:\"Scheme\"}),\". Nestas, todas as expressões têm o mesmo tipo, portanto, não há\\nrestrições em como as expressões podem ser combinadas - assim, a mesma expressão\\ndo exemplo anterior seria um construção válida, pois seria uma expressão do tipo\\n\",a(o.code,{children:\"Object\"}),\" + \",a(o.code,{children:\"Object\"}),\" - ou algo assim.\"]}),\"\\n\",n(o.p,{children:[\"Atualmente - até onde eu sei - exemplos que temos de mais poderosos e\\nexpressivos em relação a sistemas de tipos são os de\\n\",a(o.a,{href:\"http://wiki.portal.chalmers.se/agda/pmwiki.php\",children:\"Agda\"}),\",\\n\",a(o.a,{href:\"http://www.idris-lang.org/\",children:\"Idris\"}),\" e \",a(o.a,{href:\"https://coq.inria.fr/\",children:\"Coq\"}),\", que possuem\\ntipagem dependente e indutiva - programar nestas é realmente uma experiência\\nincrÃvel de interação com seu \",a(o.em,{children:\"typechecker\"}),\".\"]}),\"\\n\",n(o.p,{children:[\"Um pouco mais abaixo - mas ainda proporcionando lindezas relacionadas a tipos -\\ntemos aquelas que se baseiam em variações do modelo \",a(o.em,{children:\"HindleyâMilner\"}),\" - do qual\\nvocê pode achar uma explicação bem interessante\\n\",a(o.a,{href:\"http://akgupta.ca/blog/2013/05/14/so-you-still-dont-understand-hindley-milner/\",children:\"aqui\"}),\"\\n-, como \",a(o.em,{children:\"Haskell\"}),\", \",a(o.em,{children:\"ML\"}),\", \",a(o.em,{children:\"OCaml\"}),\", \",a(o.a,{href:\"https://www.rust-lang.org/\",children:\"Rust\"}),\",\\n\",a(o.a,{href:\"http://scala-lang.org/\",children:\"Scala\"}),\" e... \",a(o.em,{children:\"Swift\"}),\".\"]}),\"\\n\",n(o.p,{children:[\"Ainda sobre classificações, temos que \",a(o.em,{children:\"Swift\"}),\" é:\"]}),\"\\n\",n(o.ul,{children:[\"\\n\",n(o.li,{children:[a(o.strong,{children:\"Estaticamente Tipada\"}),\": Ou seja, todas as suas \",a(o.em,{children:\"variáveis\"}),\", \",a(o.em,{children:\"constantes\"}),\",\\n\",a(o.em,{children:\"funções\"}),\" etc. devem ter seus tipos declarados - ou inferidos, como veremos\\nmais adiante - antecipadamente. Então o compilador, ao compilar seu programa,\\nusa essas declarações de tipo para verificar se não há erros. Se houver um\\nerro de tipo, o programa não será compilado.\"]}),\"\\n\"]}),\"\\n\",a(o.pre,{className:\"language-swift\",children:n(o.code,{className:\"language-swift code-highlight\",children:[n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token keyword\",children:\"var\"}),\" x\",a(o.span,{className:\"token punctuation\",children:\":\"}),\" \",a(o.span,{className:\"token class-name\",children:\"Int\"}),\" \",a(o.span,{className:\"token operator\",children:\"=\"}),\" \",a(o.span,{className:\"token number\",children:\"5\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[\"x \",a(o.span,{className:\"token operator\",children:\"=\"}),\" \",a(o.span,{className:\"token string-literal\",children:a(o.span,{className:\"token string\",children:'\"Swift\"'})}),\" \",a(o.span,{className:\"token comment\",children:\"// =\u003e Aqui temos um erro\"}),\"\\n\"]})]})}),\"\\n\",n(o.ul,{children:[\"\\n\",n(o.li,{children:[a(o.strong,{children:\"Fortemente Tipada\"}),\": O que nos diz que, sempre que você usar uma variável,\\nou passar algo como um argumento de uma função, Swift irá verificar, em tempo\\nde compilação, se este é do tipo correto - assim você não pode, por exemplo,\\npassar um \",a(o.code,{children:\"Float\"}),\" para uma função que espera um \",a(o.code,{children:\"Int\"}),\".\"]}),\"\\n\"]}),\"\\n\",a(o.pre,{className:\"language-swift\",children:n(o.code,{className:\"language-swift code-highlight\",children:[n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// Uma simples função que retorna o fatorial de um valor.\"}),\"\\n\"]}),a(o.span,{className:\"code-line\",children:\"\\n\"}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// Pela anotação de tipo, temos que fatorial recebe um `Int` e o mapeia para\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// um `Int`.\"}),\"\\n\"]}),a(o.span,{className:\"code-line\",children:\"\\n\"}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token keyword\",children:\"func\"}),\" \",a(o.span,{className:\"token function-definition function\",children:\"fatorial\"}),a(o.span,{className:\"token punctuation\",children:\"(\"}),\"n\",a(o.span,{className:\"token punctuation\",children:\":\"}),\" \",a(o.span,{className:\"token class-name\",children:\"Int\"}),a(o.span,{className:\"token punctuation\",children:\")\"}),\" \",a(o.span,{className:\"token operator\",children:\"-\u003e\"}),\" \",a(o.span,{className:\"token class-name\",children:\"Int\"}),\" \",a(o.span,{className:\"token punctuation\",children:\"{\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[\" \",a(o.span,{className:\"token keyword\",children:\"return\"}),\" n \",a(o.span,{className:\"token operator\",children:\"==\"}),\" \",a(o.span,{className:\"token number\",children:\"0\"}),\" \",a(o.span,{className:\"token operator\",children:\"?\"}),\" \",a(o.span,{className:\"token number\",children:\"1\"}),\" \",a(o.span,{className:\"token punctuation\",children:\":\"}),\" n \",a(o.span,{className:\"token operator\",children:\"*\"}),\" \",a(o.span,{className:\"token function\",children:\"fatorial\"}),a(o.span,{className:\"token punctuation\",children:\"(\"}),\"nâââ\",a(o.span,{className:\"token number\",children:\"1\"}),a(o.span,{className:\"token punctuation\",children:\")\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token punctuation\",children:\"}\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// Chamando nossa função com um `Int`, teremos um `Int` de retorno.\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token function\",children:\"fatorial\"}),a(o.span,{className:\"token punctuation\",children:\"(\"}),a(o.span,{className:\"token number\",children:\"3\"}),a(o.span,{className:\"token punctuation\",children:\")\"}),\" \",a(o.span,{className:\"token comment\",children:\"// =\u003e 6\"}),\"\\n\"]}),a(o.span,{className:\"code-line\",children:\"\\n\"}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// Chamando nossa função com um `Float`, teremos um erro.\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token function\",children:\"fatorial\"}),a(o.span,{className:\"token punctuation\",children:\"(\"}),a(o.span,{className:\"token number\",children:\"3.0\"}),a(o.span,{className:\"token punctuation\",children:\")\"}),\" \",a(o.span,{className:\"token comment\",children:\"// =\u003e Erro.\"}),\"\\n\"]})]})}),\"\\n\",a(o.p,{children:\"E agora...\"}),\"\\n\",n(o.h2,{id:\"vamos-falar-de-swift\",children:[a(o.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#vamos-falar-de-swift\",children:a(o.span,{className:\"icon icon-link\"})}),\"Vamos Falar de Swift?\"]}),\"\\n\",n(o.blockquote,{children:[\"\\n\",a(o.p,{children:a(o.em,{children:'Ufa, finalmente! Um post intitulado \"Swift In The Sky With Types\" e até agora\\nnada demais
2sobre Swift?!'})}),\"\\n\"]}),\"\\n\",a(o.p,{children:\"Agora, gostaria de levantar algumas coisas que vão além do que vimos na seção\\nanterior.\"}),\"\\n\",n(o.h3,{id:\"type-safety\",children:[a(o.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#type-safety\",children:a(o.span,{className:\"icon icon-link\"})}),a(o.em,{children:\"Type-Safety\"})]}),\"\\n\",a(o.p,{children:a(o.img,{src:\"/content/posts/swift-in-the-sky-with-types/type-safety.png\",alt:\"Type-Safety\"})}),\"\\n\",n(o.p,{children:[\"Como podemos encontrar na própria\\n\",a(o.a,{href:\"https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-ID309\",children:\"documentação provida pela Apple\"}),\":\"]}),\"\\n\",n(o.blockquote,{children:[\"\\n\",n(o.p,{children:[\"Swift é uma linguagem \",a(o.em,{children:\"type-safe\"}),\", o que significa que a linguagem ajuda você\\na ser claro sobre os tipos dos valores com os quais seu código pode trabalhar.\\nSe parte do seu código espera uma \",a(o.code,{children:\"String\"}),\", a segurança de tipos impede que\\nvocê possa, por engano, passar um \",a(o.code,{children:\"Int\"}),\".\"]}),\"\\n\"]}),\"\\n\",n(o.p,{children:[\"Assim, sabemos que \",a(o.strong,{children:\"todas\"}),\" as variáveis têm um tipo declarado e \",a(o.strong,{children:\"todas\"}),\" as\\nfunções/métodos têm assinaturas de tipo que declaram os tipos de seus argumentos\\ne retornos. E por fim, o nosso amigo compilador verifica se todos os seus tipos\\nestão coerentes e não compila seu programa caso não estejam - erros em tempo de\\ncompilação são \",a(o.span,{role:\"img\",\"aria-label\":\"sparkling heart\",children:\"ð\"}),\".\"]}),\"\\n\",n(o.blockquote,{children:[\"\\n\",n(o.p,{children:[a(o.em,{children:\"Bônus\"}),': Swift nos permite definir várias \"versões\" de uma mesma função, só\\nque com diferentes assinaturas de tipos - e a \"versão\" que será chamada será\\naquela cujos argumentos forem compatÃveis com a assinatura de tipo -\\ninclusive, há um monte de coisas legais relacionadas à Swift e seu suporte a\\npolimorfismo Ad-hoc.']}),\"\\n\"]}),\"\\n\",a(o.pre,{className:\"language-swift\",children:n(o.code,{className:\"language-swift code-highlight\",children:[a(o.span,{className:\"code-line\",children:\"\\n\"}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// Uma simples função que retorna o fatorial de um valor.\"}),\"\\n\"]}),a(o.span,{className:\"code-line\",children:\"\\n\"}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// Pela anotação de tipo, temos que fatorial recebe um `Int` e o mapeia para\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// um `Int`.\"}),\"\\n\"]}),a(o.span,{className:\"code-line\",children:\"\\n\"}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token keyword\",children:\"func\"}),\" \",a(o.span,{className:\"token function-definition function\",children:\"fatorial\"}),a(o.span,{className:\"token punctuation\",children:\"(\"}),\"n\",a(o.span,{className:\"token punctuation\",children:\":\"}),\" \",a(o.span,{className:\"token class-name\",children:\"Int\"}),a(o.span,{className:\"token punctuation\",children:\")\"}),\" \",a(o.span,{className:\"token operator\",children:\"-\u003e\"}),\" \",a(o.span,{className:\"token class-name\",children:\"Int\"}),\" \",a(o.span,{className:\"token punctuation\",children:\"{\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[\" \",a(o.span,{className:\"token keyword\",children:\"return\"}),\" n \",a(o.span,{className:\"token operator\",children:\"==\"}),\" \",a(o.span,{className:\"token number\",children:\"0\"}),\" \",a(o.span,{className:\"token operator\",children:\"?\"}),\" \",a(o.span,{className:\"token number\",children:\"1\"}),\" \",a(o.span,{className:\"token punctuation\",children:\":\"}),\" n \",a(o.span,{className:\"token operator\",children:\"*\"}),\" \",a(o.span,{className:\"token function\",children:\"fatorial\"}),a(o.span,{className:\"token punctuation\",children:\"(\"}),\"nâââ\",a(o.span,{className:\"token number\",children:\"1\"}),a(o.span,{className:\"token punctuation\",children:\")\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token punctuation\",children:\"}\"}),\"\\n\"]}),a(o.span,{className:\"code-line\",children:\"\\n\"}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// Agora, pela anotação de tipo, temos que fatorial recebe um `Float` e\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// mapeia este para um `Float`.\"}),\"\\n\"]}),a(o.span,{className:\"code-line\",children:\"\\n\"}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token keyword\",children:\"func\"}),\" \",a(o.span,{className:\"token function-definition function\",children:\"fatorial\"}),a(o.span,{className:\"token punctuation\",children:\"(\"}),\"n\",a(o.span,{className:\"token punctuation\",children:\":\"}),\" \",a(o.span,{className:\"token class-name\",children:\"Float\"}),a(o.span,{className:\"token punctuation\",children:\")\"}),\" \",a(o.span,{className:\"token operator\",children:\"-\u003e\"}),\" \",a(o.span,{className:\"token class-name\",children:\"Float\"}),\" \",a(o.span,{className:\"token punctuation\",children:\"{\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[\" \",a(o.span,{className:\"token keyword\",children:\"return\"}),\" n \",a(o.span,{className:\"token operator\",children:\"==\"}),\" \",a(o.span,{className:\"token number\",children:\"0.0\"}),\" \",a(o.span,{className:\"token operator\",children:\"?\"}),\" \",a(o.span,{className:\"token number\",children:\"1.0\"}),\" \",a(o.span,{className:\"token punctuation\",children:\":\"}),\" n \",a(o.span,{className:\"token operator\",children:\"*\"}),\" \",a(o.span,{className:\"token function\",children:\"fatorial\"}),a(o.span,{className:\"token punctuation\",children:\"(\"}),\"nâââ\",a(o.span,{className:\"token number\",children:\"1.0\"}),a(o.span,{className:\"token punctuation\",children:\")\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token punctuation\",children:\"}\"}),\"\\n\"]}),a(o.span,{className:\"code-line\",children:\"\\n\"}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// Chamando nossa função com um `Int`, teremos um `Int` de retorno.\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token function\",children:\"fatorial\"}),a(o.span,{className:\"token punctuation\",children:\"(\"}),a(o.span,{className:\"token number\",children:\"3\"}),a(o.span,{className:\"token punctuation\",children:\")\"}),\" \",a(o.span,{className:\"token comment\",children:\"// =\u003e 6\"}),\"\\n\"]}),a(o.span,{className:\"code-line\",children:\"\\n\"}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// Chamando nossa função com um `Float`, teremos um `Float` de retorno.\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token function\",children:\"fatorial\"}),a(o.span,{className:\"token punctuation\",children:\"(\"}),a(o.span,{className:\"token number\",children:\"3.0\"}),a(o.span,{className:\"token punctuation\",children:\")\"}),\" \",a(o.span,{className:\"token comment\",children:\"// =\u003e 6.0\"}),\"\\n\"]})]})}),\"\\n\",n(o.h3,{id:\"type-inference\",children:[a(o.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#type-inference\",children:a(o.span,{className:\"icon icon-link\"})}),a(o.em,{children:\"Type Inference\"})]}),\"\\n\",a(o.p,{children:a(o.img,{src:\"/content/posts/swift-in-the-sky-with-types/type-inference.png\",alt:\"Type Inference\"})}),\"\\n\",n(o.p,{children:[\"Se você é daqueles que se assusta com a possibilidade de ter que declarar tipo\\nde cada variável do seu código, relaxe! Swift usa a inferência de tipos para -\\n\",\"adivinha?\",\" - inferir quais os tipos suas variáveis têm. Caso\\nqueira, você pode declarar explicitamente o tipo de suas variáveis, mas, na\\nprática, muitas vezes você não precisa: Swift irá inferir o tipo de uma \",a(o.code,{children:\"var\"}),\" se\\nvocê atribuir a ela um valor inicial.\"]}),\"\\n\",a(o.pre,{className:\"language-swift\",children:n(o.code,{className:\"language-swift code-highlight\",children:[n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// Aqui, inicializamos uma variável `x`, dando a esta o valor `1`. Como\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// fornecemos um valor inicial, não precisamos declarar explicitamente o tipo\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// de `x`: Swift irá inferir que esta se trata de um `Int`.\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token keyword\",children:\"var\"}),\" x \",a(o.span,{className:\"token operator\",children:\"=\"}),\" \",a(o.span,{className:\"token number\",children:\"1\"}),\"\\n\"]}),a(o.span,{className:\"code-line\",children:\"\\n\"}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// Desta vez, declaramos uma variável, mas sem atribuir valor a esta - assim,\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// Swift não pode inferir seu tipo e precisamos definir este explicitamente.\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// Logo após a declaração, atribuÃmos a ela o valor `2` - e caso atribuÃssemos\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// um valor de tipo não coerente com a declaração, terÃamos um erro do compilador.\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token keyword\",children:\"var\"}),\" y\",a(o.span,{className:\"token punctuation\",children:\":\"}),a(o.span,{className:\"token class-name\",children:\"Int\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[\"y \",a(o.span,{className:\"token operator\",children:\"=\"}),\" \",a(o.span,{className:\"token number\",children:\"2\"}),\"\\n\"]})]})}),\"\\n\",n(o.h3,{id:\"generics\",children:[a(o.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#generics\",children:a(o.span,{className:\"icon icon-link\"})}),a(o.em,{children:\"Generics\"})]}),\"\\n\",a(o.p,{children:a(o.img,{src:\"/content/posts/swift-in-the-sky-with-types/generics.png\",alt:\"Generics\"})}),\"\\n\",n(o.p,{children:[\"Os conhecidos \",a(o.em,{children:\"Generics\"}),\" nos permitem declarar uma variável que, na execução,\\npode ser atribuÃdo a um conjunto de tipos definidos por nós.\"]}),\"\\n\",n(o.p,{children:[\"Em Swift, um \",a(o.em,{children:\"array\"}),\" pode conter dados de qualquer tipo: ao criarmos um \",a(o.em,{children:\"array\"}),\"\\nde \",a(o.code,{children:\"Int\"}),\"s, \",a(o.code,{children:\"Float\"}),\"s ou \",a(o.code,{children:\"String\"}
2),\"s, por exemplo, o tipo dos valores que este vai\\ncarregar é definido quando o mesmo é declarado - e assim, temos neles um bom\\nexemplo do uso de \",a(o.em,{children:\"Generics\"}),\".\"]}),\"\\n\",n(o.p,{children:[\"O uso destes começa com \",a(o.strong,{children:\"funções genéricas\"}),\", como uma simples função para\\nimprimir elementos de um array:\"]}),\"\\n\",a(o.pre,{className:\"language-swift\",children:n(o.code,{className:\"language-swift code-highlight\",children:[n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// Funções genéricas usam placeholders ao invés de um tipo real, como `String`,\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// `Int` ou `Float`. Em nossa função, o placeholder é `T` - mas poderia ser\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:'// qualquer outro: `T` é \"apenas\" convenção.'}),\"\\n\"]}),a(o.span,{className:\"code-line\",children:\"\\n\"}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// O uso do placeholder não indica que a função aceita um tipo `T` mas sim que\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// `T` será substituÃdo por um tipo real que é determinada quando a função é\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// chamada.\"}),\"\\n\"]}),a(o.span,{className:\"code-line\",children:\"\\n\"}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token keyword\",children:\"func\"}),\" \",a(o.span,{className:\"token function-definition function\",children:\"imprimeElementos\"}),a(o.span,{className:\"token operator\",children:\"\u003c\"}),a(o.span,{className:\"token class-name\",children:\"T\"}),a(o.span,{className:\"token operator\",children:\"\u003e\"}),a(o.span,{className:\"token punctuation\",children:\"(\"}),\"a\",a(o.span,{className:\"token punctuation\",children:\":\"}),\" \",a(o.span,{className:\"token punctuation\",children:\"[\"}),a(o.span,{className:\"token class-name\",children:\"T\"}),a(o.span,{className:\"token punctuation\",children:\"]\"}),a(o.span,{className:\"token punctuation\",children:\")\"}),\" \",a(o.span,{className:\"token punctuation\",children:\"{\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[\" \",a(o.span,{className:\"token keyword\",children:\"for\"}),\" elemento \",a(o.span,{className:\"token keyword\",children:\"in\"}),\" a \",a(o.span,{className:\"token punctuation\",children:\"{\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[\" \",a(o.span,{className:\"token function\",children:\"println\"}),a(o.span,{className:\"token punctuation\",children:\"(\"}),\"elemento\",a(o.span,{className:\"token punctuation\",children:\")\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[\" \",a(o.span,{className:\"token punctuation\",children:\"}\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token punctuation\",children:\"}\"}),\"\\n\"]})]})}),\"\\n\",a(o.p,{children:\"E a brincadeira com estas pode ir além: poderÃamos, por exemplo, ter algo do\\ntipo:\"}),\"\\n\",a(o.pre,{className:\"language-swift\",children:a(o.code,{className:\"language-swift code-highlight\",children:n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token keyword\",children:\"func\"}),\" \",a(o.span,{className:\"token function-definition function\",children:\"minhaFuncao\"}),a(o.span,{className:\"token operator\",children:\"\u003c\"}),a(o.span,{className:\"token class-name\",children:\"T\"}),a(o.span,{className:\"token punctuation\",children:\",\"}),\" \",a(o.span,{className:\"token class-name\",children:\"U\"}),a(o.span,{className:\"token operator\",children:\"\u003e\"}),a(o.span,{className:\"token punctuation\",children:\"(\"}),\"a\",a(o.span,{className:\"token punctuation\",children:\":\"}),\" \",a(o.span,{className:\"token class-name\",children:\"T\"}),a(o.span,{className:\"token punctuation\",children:\",\"}),\" b\",a(o.span,{className:\"token punctuation\",children:\":\"}),\" \",a(o.span,{className:\"token class-name\",children:\"U\"}),a(o.span,{className:\"token punctuation\",children:\")\"}),\" \",a(o.span,{className:\"token punctuation\",children:\"{\"}),a(o.span,{className:\"token punctuation\",children:\"}\"}),\"\\n\"]})})}),\"\\n\",n(o.p,{children:[\"Onde especificamos mais de um \",a(o.em,{children:\"Generic\"}),\".\"]}),\"\\n\",n(o.p,{children:[\"Porém, a diversão não para nas funções genéricas: temos os tipos genéricos!\\nEstes são, basicamente, \",a(o.em,{children:\"classes\"}),\", \",a(o.em,{children:\"enumerations\"}),\" e \",a(o.em,{children:\"structs\"}),\" que trabalham com\\nqualquer tipo - se você se lembrou de \",a(o.em,{children:\"array\"}),\"s e \",a(o.em,{children:\"dictionaries\"}),\", você pegou a\\nideia.\"]}),\"\\n\",a(o.p,{children:\"Assim, podemos ter coisas como:\"}),\"\\n\",a(o.pre,{className:\"language-swift\",children:n(o.code,{className:\"language-swift code-highlight\",children:[n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// Um exemplo de necessidade comum, por exemplo, é obter um valor randômico de\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// uma coleção - e podemos implementar isso com Generics!\"}),\"\\n\"]}),a(o.span,{className:\"code-line\",children:\"\\n\"}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token comment\",children:\"// Temos uma estrutura que é genérica sobre o t
2ipo `T`.\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token keyword\",children:\"struct\"}),\" \",a(o.span,{className:\"token class-name\",children:\"MinhaColecao\"}),a(o.span,{className:\"token operator\",children:\"\u003c\"}),a(o.span,{className:\"token class-name\",children:\"T\"}),a(o.span,{className:\"token operator\",children:\"\u003e\"}),\" \",a(o.span,{className:\"token punctuation\",children:\"{\"}),\"\\n\"]}),a(o.span,{className:\"code-line\",children:\"\\n\"}),n(o.span,{className:\"code-line\",children:[\" \",a(o.span,{className:\"token comment\",children:\"// Temos uma propriedade, um array do tipo T para armazenar o conjunto de\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[\" \",a(o.span,{className:\"token comment\",children:\"// dados passados durante a inicialização.\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[\" \",a(o.span,{className:\"token keyword\",children:\"let\"}),\" itens\",a(o.span,{className:\"token punctuation\",children:\":\"}),\" \",a(o.span,{className:\"token punctuation\",children:\"[\"}),a(o.span,{className:\"token class-name\",children:\"T\"}),a(o.span,{className:\"token punctuation\",children:\"]\"}),\"\\n\"]}),a(o.span,{className:\"code-line\",children:\"\\n\"}),n(o.span,{className:\"code-line\",children:[\" \",a(o.span,{className:\"token keyword\",children:\"init\"}),a(o.span,{className:\"token punctuation\",children:\"(\"}),\"itens\",a(o.span,{className:\"token punctuation\",children:\":\"}),\" \",a(o.span,{className:\"token punctuation\",children:\"[\"}),a(o.span,{className:\"token class-name\",children:\"T\"}),a(o.span,{className:\"token punctuation\",children:\"]\"}),a(o.span,{className:\"token punctuation\",children:\")\"}),\" \",a(o.span,{className:\"token punctuation\",children:\"{\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[\" \",a(o.span,{className:\"token keyword\",children:\"self\"}),a(o.span,{className:\"token punctuation\",children:\".\"}),\"itens \",a(o.span,{className:\"token operator\",children:\"=\"}),\" itens\\n\"]}),n(o.span,{className:\"code-line\",children:[\" \",a(o.span,{className:\"token punctuation\",children:\"}\"}),\"\\n\"]}),a(o.span,{className:\"code-line\",children:\"\\n\"}),n(o.span,{className:\"code-line\",children:[\" \",a(o.span,{className:\"token comment\",children:\"// E, por fim, temos uma função genérica que cuida do resto :)\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[\" \",a(o.span,{className:\"token keyword\",children:\"func\"}),\" \",a(o.span,{className:\"token function-definition function\",children:\"geraAleatorio\"}),a(o.span,{className:\"token punctuation\",children:\"(\"}),a(o.span,{className:\"token punctuation\",children:\")\"}),\" \",a(o.span,{className:\"token operator\",children:\"-\u003e\"}),\" \",a(o.span,{className:\"token class-name\",children:\"T\"}),\" \",a(o.span,{className:\"token punctuation\",children:\"{\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[\" \",a(o.span,{className:\"token keyword\",children:\"let\"}),\" indice \",a(o.span,{className:\"token operator\",children:\"=\"}),\" \",a(o.span,{className:\"token class-name\",children:\"Int\"}),a(o.span,{className:\"token punctuation\",children:\"(\"}),a(o.span,{className:\"token function\",children:\"arc4random_uniform\"}),a(o.span,{className:\"token punctuation\",children:\"(\"}),a(o.span,{className:\"token class-name\",children:\"UInt32\"}),a(o.span,{className:\"token punctuation\",children:\"(\"}),\"itens\",a(o.span,{className:\"token punctuation\",children:\".\"}),\"count\",a(o.span,{className:\"token punctuation\",children:\")\"}),a(o.span,{className:\"token punctuation\",children:\")\"}),a(o.span,{className:\"token punctuation\",children:\")\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[\" \",a(o.span,{className:\"token keyword\",children:\"return\"}),\" itens\",a(o.span,{className:\"token punctuation\",children:\"[\"}),\"indice\",a(o.span,{className:\"token punctuation\",children:\"]\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[\" \",a(o.span,{className:\"token punctuation\",children:\"}\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token punctuation\",children:\"}\"}),\"\\n\"]})]})}),\"\\n\",a(o.p,{children:\"E, ao testarmos:\"}),\"\\n\",a(o.pre,{className:\"language-swift\",children:n(o.code,{className:\"language-swift code-highlight\",children:[n(o.span,{className:\"code-line\",children:[a(o.span,{className:\"token keyword\",children:\"let\"}),\" teste \",a(o.span,{className:\"token operator\",children:\"=\"}),\" \",a(o.span,{className:\"token class-name\",children:\"MinhaColecao\"}),a(o.span,{className:\"token punctuation\",children:\"(\"}),\"itens\",a(o.span,{className:\"token punctuation\",children:\":\"}),\" \",a(o.span,{className:\"token punctuation\",children:\"[\"}),a(o.span,{className:\"token string-literal\",children:a(o.span,{className:\"token string\",children:'\"s\"'})}),a(o.span,{className:\"token punctuation\",children:\",\"}),\" \",a(o.span,{className:\"token string-literal\",children:a(o.span,{className:\"token string\",children:'\"w\"'})}),a(o.span,{className:\"token punctuation\",children:\",\"}),\" \",a(o.span,{className:\"token string-literal\",children:a(o.span,{className:\"token string\",children:'\"i\"'})}),a(o.span,{className:\"token punctuation\",children:\",\"}),\" \",a(o.span,{className:\"token string-literal\",children:a(o.span,{className:\"token string\",children:'\"f\"'})}),a(o.span,{className:\"token punctuation\",children:\",\"}),\" \",a(o.span,{className:\"token string-literal\",children:a(o.span,{className:\"token string\",children:'\"t\"'})}),a(o.span,{className:\"token punctuation\",children:\"]\"}),a(o.span,{className:\"token punctuation\",children:\")\"}),\"\\n\"]}),n(o.span,{className:\"code-line\",children:[\"teste\",a(o.span,{className:\"token punctuation\",children:\".\"}),a(o.span,{className:\"token function\",children:\"geraAleatorio\"}),a(o.span,{className:\"token punctuation\",children:\"(\"}),a(o.span,{className:\"token punctuation\",children:\")\"}),\" \",a(o.span,{className:\"token comment\",children:'// =\u003e \"f\"'}),\"\\n\"]})]})}),\"\\n\",n(o.h2,{id:\"concluindo\",children:[a(o.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#concluindo\",children:a(o.span,{className:\"icon icon-link\"})}),\"Concluindo\"]}),\"\\n\",n(o.blockquote,{children:[\"\\n\",a(o.p,{children:\"Falou quase nada de Swift!\"}),\"\\n\"]}),\"\\n\",n(o.p,{children:[\"Ã... Verdade! Perto do que se tem a ser dito, não foi dito quase nada de nada.\\nCada um desses tópicos sobre Swift - até os mais primitivos -, juntamente com\\nalguns que não explorei para evitar textão - como \",a(o.em,{children:\"Phantom Types\"}),\", \",a(o.em,{children:\"Typeclasses\"}),\"\\netc. - renderia/mereceria um post ou talk sobre. E com os tópicos mais teóricos\\ndiscutidos no post não é muito diferente - de fato, é sim: estes é que\\nrenderiam/mereceriam mais posts e talks para serem discutidos!\"]}),\"\\n\",a(o.p,{children:\"Na verdade, o objetivo maior do post é apenas levantar cada um destes tópicos em\\nsua mente - e o fazer pensar e buscar mais sobre eles.\"}),\"\\n\",n(o.blockquote,{children:[\"\\n\",a(o.p,{children:\"Eu realmente ganho algo?\"}),\"\\n\"]}),\"\\n\",n(o.p,{children:[\"Você pode ainda estar se perguntando se todas estas palavras relacionadas à \\nteoria dos tipos - e outras áreas de estudo comumente associadas a projeto e\\nimplementação de linguagem - que soam algo muito \",a(o.em,{children:\"apenas da Academia\"}
2),\" realmente\\nafetam a forma como você escreve aplicações do mundo real; para resolver\\nproblemas reais.\"]}),\"\\n\",n(o.p,{children:[\"Bem, eu confesso que, quando comecei a interessar mais por esse assunto, também\\ntinha muitos pensamentos assim - algo do tipo: \",a(o.em,{children:'\"Poxa, até ontem eu escrevia\\ncódigo que funcionava e não entendia nada disso! Não vai ser agora que vou\\nprecisar\"'}),\".\"]}),\"\\n\",a(o.p,{children:\"O que eu não me ligava muito era que a formo como eu modelo meus dados afeta - e\\nmuito! - a forma como eu interajo com estes. E:\"}),\"\\n\",n(o.ul,{children:[\"\\n\",n(o.li,{children:[\"\\n\",a(o.p,{children:\"Poder deduzir o que uma função faz a partir de sua assinatura de tipo - algo\\ninclusive muito útil para tornar o código mais legÃvel e compreensÃvel -;\"}),\"\\n\"]}),\"\\n\",n(o.li,{children:[\"\\n\",a(o.p,{children:\"Ter o processo de refatoração facilitado, uma vez que conto com um monte de\\nerros de compilação para me dizer onde as coisas começaram a dar errado;\"}),\"\\n\"]}),\"\\n\",n(o.li,{children:[\"\\n\",a(o.p,{children:\"Ter a garantia que as relações entre meus dados estão ocorrendo da forma que\\ndeveriam.\"}),\"\\n\"]}),\"\\n\"]}),\"\\n\",a(o.p,{children:\"São etapas que, diria eu, são necessárias para se atingir a coerência requerida\\npara se interagir corretamente com uma informação - e isso, colega, causa grande\\nimpacto no seu software final.\"}),\"\\n\",n(o.blockquote,{children:[\"\\n\",a(o.p,{children:\"Poxa, agora o compilador será meu inimigo?\"}),\"\\n\"]}),\"\\n\",n(o.p,{children:[a(o.strong,{children:\"tl;dr\"}),\": De forma alguma, galera.\"]}),\"\\n\",n(o.p,{children:[\"A priori, pode soar \",\"muito chato\",\" doloroso travar uma \",a(o.em,{children:'\"luta\"'}),\"\\ncontra um \",a(o.em,{children:\"typechecker\"}),\" apenas para ver um programa que você \",a(o.strong,{children:\"tem certeza de\\nque está correto\"}),\" compilado. Alguns chegam até a ver como uma péssima\\ncaracterÃstica da linguagem se pensarmos em um conceito de \",a(o.em,{children:\"bom\"}),' para uma lang\\ndefinido através da métrica \"ser ',a(o.em,{children:\"developer-friendly\"}),'\".']}),\"\\n\",n(o.p,{children:[\"Porém, um ponto que eu penso ser interessante de se discutir é o fato de que a\\nnoção técnica de \",a(o.em,{children:\"melhor\"}),\" envolve aspectos - estes indo muito além do sistema de\\ntipos, como: seu modelo de execução, o quão segura esta é, maneiras que se usa\\npra obter melhor expressividade - que nem sempre, \",a(o.strong,{children:\"à primeira vista\"}),\", se\\nalinham com a felicidade do desenvolvedor.\"]}),\"\\n\",a(o.p,{children:\"Particularmente, o tempo me mostrou que, ao programar em uma linguagem que me\\nfaça pensar cuidadosamente sobre tipos, acabo chegando a um código melhor\\nprojetado, mais fácil de manter, que falha mais rápido - caso este haja de\\nfalhar, claro -, melhor documentado etc. Assim, passei a ver o compilador não\\ncomo um inimigo, mas como uma ferramenta que me guia de uma bela forma a solução\\npara o meu problema - através de tipos.\"}),\"\\n\",n(o.p,{children:[\"E tudo isso faz você se sentir bem mais confiante sobre seu próprio código - e\\nisso é tão divertido quanto ouvir a faixa \",a(o.em,{children:\"Lucy In The Sky With Diamonds\"}),\" \",a(o.span,{role:\"img\",\"aria-label\":\"smiling face\",children:\"âºï¸\"}),\".\"]}),\"\\n\",n(o.h2,{id:\"referências\",children:[a(o.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#referências\",children:a(o.span,{className:\"icon icon-link\"})}),\"Referências\"]}),\"\\n\",a(o.p,{children:\"Aqui ficam apenas alguns posts, livros, vÃdeos etc. nos quais me baseei ao longo\\nda escrita deste post - e que eu acho que mereceriam um tempo da atenção de\\nvocês.\"}),\"\\n\",n(o.ul,{children:[\"\\n\",n(o.li,{children:[\"\\n\",n(o.p,{children:[a(o.a,{href:\"https://www.youtube.com/watch?v=52VsgyexS8Q\u0026feature=youtu.be\",children:\"Hole-driven Haskell\"}),\"\\nâ \",a(o.em,{children:\"Screencast\"}),\" por \",a(o.a,{href:\"http://matthew.brecknell.net/\",children:\"Matthew Brecknell\"}),\".\"]}),\"\\n\"]}),\"\\n\",n(o.li,{children:[\"\\n\",n(o.p,{children:[a(o.a,{href:\"https://www.youtube.com/watch?v=gVXt1RG_yN0\",children:\"May Your Data Ever Be Coherent\"}),\"\\nâ \",a(o.em,{children:\"Talk\"}),\" por \",a(o.a,{href:\"http://www.codecommit.com/blog/\",children:\"Daniel Spiewak\"}),\".\"]}),\"\\n\"]}),\"\\n\",n(o.li,{children:[\"\\n\",n(o.p,{children:[a(o.a,{href:\"http://lucacardelli.name/papers/onunderstanding.a4.pdf\",children:\"On Understanding Types,Data Abstraction, and Polymorphism\"}),\"\\nâ Artigo por \",a(o.a,{href:\"http://lucacardelli.name/\",children:\"Luca Cardelli\"}),\".\"]}),\"\\n\"]}),\"\\n\",n(o.li,{children:[\"\\n\",n(o.p,{children:[a(o.a,{href:\"https://mitpress.mit.edu/sicp/full-text/book/book.html\",children:\"Structure and Interpretation of Computer Programs\"}),\"\\nâ O famoso \",a(o.em,{children:\"Livro do Mago\"}),\" é sempre uma referência!\"]}),\"\\n\"]}),\"\\n\",n(o.li,{children:[\"\\n\",n(o.p,{children:[a(o.a,{href:\"https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html\",children:\"The Swift Programming Language (Swift 2.2) - The Basics\"}),\"\\nâ Documentação oficial provida pela Apple.\"]}),\"\\n\"]}),\"\\n\",n(o.li,{children:[\"\\n\",n(o.p,{children:[a(o.a,{href:\"http://lucacardelli.name/Papers/TypeSystems.pdf\",children:\"Type Systems\"}),\" â Artigo por\\n\",a(o.a,{href:\"http://lucacardelli.name/\",children:\"Luca Cardelli\"}),\".\"]}),\"\\n\"]}),\"\\n\",n(o.li,{children:[\"\\n\",n(o.p,{children:[a(o.a,{href:\"https://www.cis.upenn.edu/~bcpierce/tapl/\",children:\"Types and Programming Languages\"}),\" â\\nLivro de \",a(o.a,{href:\"http://www.cis.upenn.edu/~bcpierce/\",children:\"Benjamin Pierce\"}),\".\"]}),\"\\n\"]}),\"\\n\"]})]})}return{default:function(e={}){const{wrapper:n}=e.components||{};return n?a(n,{...e,children:a(_createMdxContent,{...e})}):_createMdxContent(e)}};"},"_tags":["swift","type systems"]},{"title":"O que há de novo com o AngularJS?","date":"2014-11-10T00:00:00.000Z","summary":"Mudanças anunciadas na ng-Europe, a versão 1.3, âmorteâ de APIs⦠O AngularJS 2.0 ainda será o AngularJS que conhecemos?","language":"pt","tags":["angular"],"slug":"o-que-ha-de-novo-com-o-angularjs","hero":"/content/posts/o-que-ha-de-novo-com-o-angularjs/hero.png","readingTime":{"text":"8 min read","minutes":7.61,"time":456600,"w
2ords":1522},"body":{"code":"const{Fragment:e,jsx:a,jsxs:o}=arguments[0];function _createMdxContent(s){const n={a:\"a\",code:\"code\",h2:\"h2\",h3:\"h3\",p:\"p\",span:\"span\",strong:\"strong\",...s.components};return o(e,{children:[a(n.p,{children:\"Mudanças anunciadas na ng-Europe, a versão 1.3, âmorteâ de APIs⦠O AngularJS 2.0\\nainda será o AngularJS que conhecemos?\"}),\"\\n\",a(n.p,{children:\"Decidi escrever este post para compartilhar um pouco do que penso sobre o que\\ntem acontecido ao longo dos últimos dias desde a ng-europe e o que esperar â ou\\nnão â do Angular2.0. Eu não pretendo que esse post seja algo muito técnico nem\\npenso que ele irá cobrir todos os detalhes, mas eu realmente gostaria de falar\\nsobre as minhas impressões e fazer alguns comentários sobre alguns tópicos\\nespecÃficos e anúncios que chamaram a minha atenção.\"}),\"\\n\",a(n.p,{children:\"Como todos sabem, a ng-europe é, como o próprio nome diz, a conferência europeia\\ndedicada ao nosso querido AngularJS. Antes dela tivemos a ng-conf, que aconteceu\\nno inÃcio deste ano, em Utah, nos EUA. Assim como na ng-conf, muitos\\ndesenvolvedores estavam presentes (cerca de 800 pessoas) no evento.\"}),\"\\n\",a(n.p,{children:\"Mas assim, uma coisa que eu posso notar (principalmente em discussões em grupos\\nde Angular aqui no Brasil) é que, enquanto alguns estão animados com a abordagem\\nmoderna e diferente que o framework terá com sua versão 2.0, muitos estão\\nprevendo o pior - e alguns estão preocupados com o que devem fazer com seus\\nprojetos em Angular.\"}),\"\\n\",a(n.p,{children:\"Antes de eu começar, as opiniões neste post são baseadas na minha experiência\\ncom o framework â e estou muito longe de ser dono da verdade. Então, se você não\\nconcordar com nenhuma das opiniões ou informações dadas aqui, deixe seu\\ncomentário e ficarei feliz em reavaliar os meus argumentos e opiniões.\"}),\"\\n\",o(n.h2,{id:\"o-angularjs-13\",children:[a(n.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#o-angularjs-13\",children:a(n.span,{className:\"icon icon-link\"})}),\"O AngularJS 1.3\"]}),\"\\n\",a(n.p,{children:\"Agora vamos começar falando sobre a versão atual: as informações sobre Angular\\n1.3 já estão disponÃveis desde que foi lançada a versão estável â na semana\\nanterior da ng-europe, se não me engano. Confesso que eu tinha ouvido falar\\nvárias melhorias para a API da 1.3, mas eu não tinha me sentido muito animado\\ncom isso â não tinha encontrado uma razão convincente para atualizar os meus\\nprojetos atuais de 1.2.x para 1.3.\"}),\"\\n\",o(n.p,{children:[\"Mas, depois de assistir algumas palestras da ng-europe e ler alguns artigos e\\ndiscussões, estou convencido dos benefÃcios de atualização. Certamente é a\\nmelhor versão do Angular disponÃvel hoje. Ele vem com muitas correções de bugs\\n(com \",a(n.code,{children:\"$browser\"}),\", \",a(n.code,{children:\"$http\"}),\", \",a(n.code,{children:\"$injector\"}),\", \",a(n.code,{children:\"$parse\"}),\", \",a(n.code,{children:\"$location\"}),\", \",a(n.code,{children:\"$compile\"}),\" por\\nexemplo) e também apresenta melhorias â como one-time bindings, o módulo\\n\",a(n.code,{children:\"ngMessages\"}),\" e muitos outros. E, assim como novas APIs, há ainda melhorias que\\npodem render benefÃcios significativos no desempenho de seu projeto.\"]}),\"\\n\",o(n.h2,{id:\"angularjs-20\",children:[a(n.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#angularjs-20\",children:a(n.span,{className:\"icon icon-link\"})}),\"AngularJS 2.0\"]}),\"\\n\",a(n.p,{children:\"Agora, o tão esperado Angular 2.0 â o tema na mente de todo desenvolvedor\\nAngular nesse momento. Foi circulada muita informação sobre ele desde o seu\\nanúncio, mas irei comentar aqui somente alguns pontos que se destacaram mais\\npara mim.\"}),\"\\n\",o(n.h3,{id:\"matando-apis\",children:[a(n.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#matando-apis\",children:a(n.span,{className:\"icon icon-link\"})}),\"Matando APIs\"]}),\"\\n\",o(n.p,{children:[\"Penso que muitas das APIs com que você era familiar no 1.x foram âmassacradasâ:\\n\",a(n.strong,{children:\"controladores\"}),\", \",a(n.strong,{children:\"Directive Definition Objects (DDOs)\"}),\", \",a(n.code,{children:\"angular.module\"}),\",\\n\",a(n.strong,{children:\"jqLite\"}),\" e o \",a(n.code,{children:\"$scope\"}),\" â sim, até o \",a(n.code,{children:\"$scope\"}),\". Confesso que, na primeira vez que\\neu vi isso, eu pensei sobre o tempo que gastei estudando as APIs atuais e fiquei\\nmuito chateado. Mas agora eu estou contente de ver o que está por vir.\"]}),\"\\n\",o(n.p,{children:[\"Entre essas mudanças, eu gostaria de falar sobre a remoção do jqLite e enfatizar\\na do \",a(n.code,{children:\"$scope\"}),\". A primeira é justificada pelo fato de que a inclusão de jQlite\\nafeta muito o desempenho. Micro-otimização foi tentada mas, cá entre nós, é\\nmuito melhor operar com a API DOM nativa. Desde que o AngularJS 2.0 visa os\\nconhecidos âevergreen browsersâ, eu posso entender a mudança â até porque eu me\\nvejo usando APIs nativas cada vez mais. Ah, é válido lembrar que você ainda\\nestará livre para incluir e usar jQuery.\"]}),\"\\n\",o(n.p,{children:[\"A segunda coisa que eu gostaria de mencionar é que \",a(n.code,{children:\"$scope\"}
2),\" como uma facilidade\\nâexplÃcitaâ na API não existe mais. Há apenas um controlador. O scope ainda está\\nfazendo o seu trabalho ânos bastidoresâ â mas nós desenvolvedores não o vemos.\"]}),\"\\n\",a(n.p,{children:\"Ao fazer isso, o Angular 2.0 não está removendo a ligação de dados e nem a\\npossibilidade de chamar funções a partir de modelos: ele está apenas retirando a\\nscope API que oferece esses recursos em versões anteriores.\"}),\"\\n\",o(n.h3,{id:\"atscript-uma-nova-linguagem\",children:[a(n.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#atscript-uma-nova-linguagem\",children:a(n.span,{className:\"icon icon-link\"})}),\"AtScript: Uma nova linguagem?\"]}),\"\\n\",a(n.p,{children:\"Eu prefiro ver o AtScript como um superset do ES6 que está sendo usado para\\ncriar o Angular 2.0. Ele usa a sintaxe de tipos do Typescript para representar\\ntipos opcionais que podem ser usados para gerar type assertions em tempo de\\nexecução, em vez de checks em tempo de compilação. Ele também estende a\\nlinguagem com anotações de metadados.\"}),\"\\n\",a(n.p,{children:\"Estou animado com o AtScript â mas levando em conta que já trabalhava com\\nTypeScript antes, vocês podem dizer que a minha opinião não conta. Um ponto que\\neu penso ser interessante sobre AtScript é que você pode aproveitar a sintaxe de\\ntipos como uma maneira simples de fornecer metadados para outras bibliotecas. Eu\\nacho que um dos recursos mais poderosos do AtScript é ter as informações de tipo\\ne metadados disponÃveis em tempo de execução para que frameworks possam usar â\\nou para usar em metaprogramação. Na verdade, não ficaria nada surpreso se outras\\nlinguagens âcopiassemâ esse recurso.\"}),\"\\n\",o(n.h3,{id:\"suporte-migração\",children:[a(n.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#suporte-migração\",children:a(n.span,{className:\"icon icon-link\"})}),\"Suporte? Migração?\"]}),\"\\n\",a(n.p,{children:\"Nesse momento você provavelmente deve estar se perguntando: âO que vai acontecer\\ncom 1.x?â, âExiste um meio de migração do 1.x para 2.0?â ou mesmo âE o suporte a\\nversões anteriores?â⦠Mas garanto que você não deve se preocupar com o suporte â\\nafinal o Google tem mais de 1600 aplicativos internos que são feitos o Angular\\n1.2 ou 1.3. Logo podemos perceber que o Google tem investido fortemente na\\nversão atual, e logo terá de oferecer suporte a ela por um bom tempo.\\nQuestionado sobre o suporte para o 1.3, uma vez que o 2.0 tivesse sido liberado,\\nBrad Green afirmou que poderÃamos esperar pelo menos entre um ano e meio ou dois\\nanos de suporte para a 1.3 após a versão final estável do Angular 2.0 ser\\nlançada. Considerando o fato de que o 2.0 ainda está em um estágio muito\\nexperimental, com muitos detalhes de implementação ainda nem sequer decididos,\\neu diria que temos alguns anos ainda de suporte total para o 1.3.\"}),\"\\n\",a(n.p,{children:\"Com relação a migrações, Rob Eisenberg (que está escrevendo o novo router do\\n2.0) afirmou que não foram anunciados ainda quaisquer planos disponibilizados a\\nrespeito de migração para aqueles que desejam passar seus aplicativos do Angular\\n1.x para o 2.0 â quando este estiver disponÃvel . Também é válido ressaltar que,\\nem sua palestra, ele disse que o router do 2.0 vai ser portado para o 1.3. Penso\\neu que talvez isso possa acontecer com outros módulos 2.0, mas temos que esperar\\ne ver.\"}),\"\\n\",o(n.h3,{id:\"ainda-é-o-angularjs-que-conhecemos-e-amamos\",children:[a(n.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#ainda-é-o-angularjs-que-conhecemos-e-amamos\",children:a(n.span,{className:\"icon icon-link\"})}),\"Ainda é o AngularJS que conhecemos (e amamos)?\"]}),\"\\n\",a(n.p,{children:\"Desde o anúncio de todas as mudanças propostas no AngularJS 2.0, muitos\\ndesenvolvedores já manifestaram suas preocupações e crÃticas sobre o que a\\nequipe está fazendo. Muitas dessas crÃticas são válidas â até porque a nova\\nversão está longe da perfeição â mas também há muita desinformação sendo\\nventilada por aÃ.\"}),\"\\n\",a(n.p,{children:\"Eu mesmo ouvi de pessoas aqui que o Angular 2.0 vai ser um framework tão\\n
2diferente que não deveria nem ser chamado de Angular e que toda a ideia por trás\\ndo Angular 1.x foi desfeita.\"}),\"\\n\",a(n.p,{children:\"Eu até posso entender um pouco a forma como se chegaram a essas conclusões â\\nafinal do jeito que as novidades do 2.0 foram apresentadas na ng-europe, era\\nfácil ter a ideia de que praticamente tudo iria mudar. Mas, quando você estuda\\num pouco mais as mudanças anunciadas, vê que não é bem o caso.\"}),\"\\n\",a(n.p,{children:\"Se pararmos pra pensar, veremos que existem alguns conceitos-chave por trás do\\nAnguarJS, como: injeção de dependências, detecção de mudanças, e DOM extensÃvel.\\nE eu, pessoalmente, não ouvi nada sobre o 2.0 que sugere o fim de qualquer um\\ndeles â nem outros conceitos importantes.\"}),\"\\n\",a(n.p,{children:\"O que irá mudar são as APIs que nós, desenvolvedores, usamos para acessar estes\\nrecursos. Algumas delas vão mudar muito. Mas os conceitos fundamentais\\npermanecerão.\"}),\"\\n\",a(n.p,{children:\"E outra: eu acho que, se você é qualquer tipo de desenvolvedor web, você tem que\\nestar preparado para possÃveis mudanças e adaptar-se a elas. Muitos outros\\nframeworks ainda vão mudar (talvez grandes, talvez pequenas mudanças â\\ndependendo de suas necessidades, foco etc.) devido à s novas tecnologias que\\nsurgem. Se eles não mudam, se tornam obsoletos em um futuro próximo, uma vez que\\no ES6 e outras tecnologias entram em cena. O desafio é decidir sobre a forma\\ncomo você vai lidar com a mudança.\"}),\"\\n\",o(n.h2,{id:\"conclusão\",children:[a(n.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#conclusão\",children:a(n.span,{className:\"icon icon-link\"})}),\"Conclusão\"]}),\"\\n\",a(n.p,{children:\"Eu confesso que estou muito animado sobre os rumos do Angular 2.0, e que estou\\nansioso para atualizar alguns de meus projetos para a 1.3 e me aproveitar das\\nmelhorias disponÃveis. Eu acho que a maioria das mudanças anunciadas para o 2.0\\nsão evolutivas, e projetadas para simplificar os padrões que muitos de nós já\\nestão usando. E eu acho que muitos outros desenvolvedores já estão percebendo a\\nmesma coisa â e assim também fez a equipe do Angular. Com o AngularJS 2.0, eles\\nestão apenas respondendo a maneira como parte da comunidade tem produzido â e\\nisso me deixa ansioso para ver o que está por vir!\"})]})}return{default:function(e={}){const{wrapper:o}=e.components||{};return o?a(o,{...e,children:a(_createMdxContent,{...e})}):_createMdxContent(e)}};"},"_tags":["angular"]}],"openGraphImage":"https://www.ythecombinator.space/content/posts/cover.png"},"__N_SSG":true},"page":"/posts","query":{},"buildId":"mzgQ2EcaywvSCBrN7ELhT","isFallback":false,"gsp":true,"scriptLoader":[]}</script>
2</body></html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.