<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: The Practical Developer</title>
    <description>The latest articles on DEV Community by The Practical Developer (@practicaldevblog).</description>
    <link>https://dev.to/practicaldevblog</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4209076%2F40e1896a-3db7-49a0-ab50-515f642b1cf2.webp</url>
      <title>DEV Community: The Practical Developer</title>
      <link>https://dev.to/practicaldevblog</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/practicaldevblog"/>
    <language>en</language>
    <item>
      <title>NGINX Explained: The Server in Front of Your Server</title>
      <dc:creator>The Practical Developer</dc:creator>
      <pubDate>Sun, 01 Nov 2026 12:51:09 +0000</pubDate>
      <link>https://dev.to/practicaldevblog/nginx-explained-the-server-in-front-of-your-server-49gn</link>
      <guid>https://dev.to/practicaldevblog/nginx-explained-the-server-in-front-of-your-server-49gn</guid>
      <description>&lt;p&gt;Most web apps do not face the internet alone. In front of them sits a server whose job is to serve files fast, hand requests to the right app, and spread load across machines. NGINX, written by Igor Sysoev and first released in 2004, is that server for a large share of the busiest sites: one process, thousands of connections, and a configuration file that reads like a set of routing rules.&lt;/p&gt;

&lt;p&gt;Static files, reverse proxies, and load balancing&lt;/p&gt;

&lt;p&gt;NGINX rests on a few distinctive ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An event-driven design: a small number of worker processes handle many connections at once, instead of one thread per visitor, which keeps memory low under heavy traffic.&lt;/li&gt;
&lt;li&gt;Static files, served directly: images, stylesheets, and scripts come straight from disk, so the app server never wastes time on work the front server can do.&lt;/li&gt;
&lt;li&gt;Reverse proxying: requests for dynamic pages are passed to an app running on another port or machine, while the visitor only ever sees NGINX.&lt;/li&gt;
&lt;li&gt;Load balancing built in: list several app servers and NGINX spreads requests across them, retrying a healthy one when another stops responding.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A tiny example shows the shape, a server block that serves static files itself and passes everything else to an app on port 3000:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;example.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://127.0.0.1:3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/static/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/var/www/html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;listen 80 takes ordinary web traffic, proxy_pass forwards a request to the app listening on the same machine at port 3000, and root inside the static location serves files from disk. A request for /static/logo.png is answered from /var/www/html/static/logo.png, while a request for /dashboard goes to the app. Test the file with nginx -t before reloading, so a typo never takes the site down.&lt;/p&gt;

&lt;p&gt;The honest trade&lt;/p&gt;

&lt;p&gt;NGINX trades application logic for speed at the edge: it is not where business rules live, its configuration syntax rewards careful reading, and debugging a proxy problem means checking two servers instead of one. When to reach for it: when an app needs static serving, secure termination, or traffic spread across servers; a plain app server alone when the project is small and none of those are needed yet.&lt;/p&gt;

&lt;p&gt;In front, quietly working&lt;/p&gt;

&lt;p&gt;NGINX is the server in front of your server: static files from disk, dynamic requests forwarded, load shared across machines, all from a short configuration file. It trades one more moving part for a front door that stays fast under pressure, and for sites that grow, that front door earns its place.&lt;/p&gt;

&lt;p&gt;Originally published at &lt;a href="https://practicaldevblog.blogspot.com/2026/11/nginx-explained-server-in-front-of-your.html" rel="noopener noreferrer"&gt;https://practicaldevblog.blogspot.com/2026/11/nginx-explained-server-in-front-of-your.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nginx</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>PyTorch Explained: Machine Learning You Can Watch Learn</title>
      <dc:creator>The Practical Developer</dc:creator>
      <pubDate>Sun, 01 Nov 2026 12:50:17 +0000</pubDate>
      <link>https://dev.to/practicaldevblog/pytorch-explained-machine-learning-you-can-watch-learn-obp</link>
      <guid>https://dev.to/practicaldevblog/pytorch-explained-machine-learning-you-can-watch-learn-obp</guid>
      <description>&lt;p&gt;TensorFlow showed one way to train a model, with layers stacked and compiled. PyTorch, released by Meta's AI research lab in 2016, takes a more hands-on approach: you write ordinary Python, tensors track their own gradients, and the training loop is a loop you can read, print from, and change. That openness made it the favourite of researchers, and it is now just as common in production, from image models to language models.&lt;/p&gt;

&lt;p&gt;Tensors, autograd, and the training loop&lt;/p&gt;

&lt;p&gt;PyTorch rests on a few distinctive ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tensors that feel like arrays: a tensor is a multi-dimensional array, like a NumPy array, with the added ability to run on a graphics card for speed.&lt;/li&gt;
&lt;li&gt;Autograd: operations on tensors remember how they were built, so calling backward fills in every gradient automatically instead of asking you to derive them by hand.&lt;/li&gt;
&lt;li&gt;Modules, composed freely: a model is a module, layers are modules inside it, and you assemble them with plain Python control flow, including loops and conditions.&lt;/li&gt;
&lt;li&gt;A training loop you own: zero the gradients, run the model, measure the loss, step the optimiser, and repeat, with every step visible in your own code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A tiny example shows the shape, a model that learns the line y = 2x + 1 from four examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;torch.nn&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;nn&lt;/span&gt;

&lt;span class="n"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tensor&lt;/span&gt;&lt;span class="p"&gt;([[&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;
&lt;span class="n"&gt;ys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tensor&lt;/span&gt;&lt;span class="p"&gt;([[&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;5.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;7.0&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;

&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Linear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;optimizer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;optim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SGD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;lr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.01&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;loss_fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;MSELoss&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;optimizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zero_grad&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;loss&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;loss_fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;ys&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;loss&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;backward&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;optimizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;step&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tensor&lt;/span&gt;&lt;span class="p"&gt;([[&lt;/span&gt;&lt;span class="mf"&gt;4.0&lt;/span&gt;&lt;span class="p"&gt;]])))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;nn.Linear(1, 1) creates one input neuron connected to one output, zero_grad clears the previous step's gradients so they do not pile up, loss.backward computes fresh gradients, and step nudges the weights a little in the direction that lowers the loss. After 200 passes, predicting for 4.0 lands near 9.0, not exactly, because training improves gradually rather than solving the equation outright.&lt;/p&gt;

&lt;p&gt;The honest trade&lt;/p&gt;

&lt;p&gt;PyTorch trades hand-holding for control: the training loop is yours to write, which means yours to debug, and moving a model into production takes extra tooling compared with a more packaged framework. When to reach for it: when you want to understand, customise, or research a neural network; a higher-level library when the model is standard and speed of setup matters more than control.&lt;/p&gt;

&lt;p&gt;Tensors, trained in the open&lt;/p&gt;

&lt;p&gt;PyTorch is machine learning you can watch learn: tensors, automatic gradients, and a training loop written out in plain Python. It trades convenience for control over every step, and for anyone who wants to see how a model actually improves, that openness is the point.&lt;/p&gt;

&lt;p&gt;Originally published at &lt;a href="https://practicaldevblog.blogspot.com/2026/11/pytorch-explained-machine-learning-you.html" rel="noopener noreferrer"&gt;https://practicaldevblog.blogspot.com/2026/11/pytorch-explained-machine-learning-you.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>pytorch</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Pandas Explained: Tables in Python, Without the Spreadsheet</title>
      <dc:creator>The Practical Developer</dc:creator>
      <pubDate>Sun, 01 Nov 2026 12:49:22 +0000</pubDate>
      <link>https://dev.to/practicaldevblog/pandas-explained-tables-in-python-without-the-spreadsheet-2983</link>
      <guid>https://dev.to/practicaldevblog/pandas-explained-tables-in-python-without-the-spreadsheet-2983</guid>
      <description>&lt;p&gt;A spreadsheet is fine until the data grows: a million rows, ten files to combine, or the same cleanup repeated every week. Pandas, a Python library created by Wes McKinney and first released in 2008, gives you spreadsheet-style tables inside code, so the cleanup is written once and runs the same way every time. It is the default first step for data work in Python, from a quick sales summary to the data preparation behind a machine learning model.&lt;/p&gt;

&lt;p&gt;DataFrames, filtering, and grouping&lt;/p&gt;

&lt;p&gt;Pandas rests on a few distinctive ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DataFrames and Series: a DataFrame is a table with named columns, a Series is a single column, and both carry labels, so rows and columns can be picked by name instead of position.&lt;/li&gt;
&lt;li&gt;Reading real files: one call loads a CSV, a spreadsheet, or a database query into a table, with missing values handled rather than silently dropped.&lt;/li&gt;
&lt;li&gt;Filtering and selecting: conditions pick out rows, column names pick out columns, and the two combine into queries that read almost like sentences.&lt;/li&gt;
&lt;li&gt;Grouping and joining: groupby summarises rows by category, merge joins tables on a shared key, and both replace the manual copying that spreadsheets encourage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A tiny example shows the shape, a sales table filtered and then totalled by city:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;

&lt;span class="n"&gt;sales&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;city&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Karachi&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Lahore&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Karachi&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="n"&gt;big_sales&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sales&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sales&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big_sales&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sales&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;groupby&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;city&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;sales["amount"] &amp;gt;= 100 builds a true/false mask, one value per row, and sales[mask] keeps only the rows where it is true, so the Karachi row of 120 survives and the other two do not. groupby("city")["amount"].sum() then adds the amounts per city, giving 200 for Karachi and 90 for Lahore. The original table is untouched; every step returns a new result.&lt;/p&gt;

&lt;p&gt;The honest trade&lt;/p&gt;

&lt;p&gt;Pandas trades memory for convenience: it loads data into memory, so very large datasets need chunking or a different tool, and its many ways to do the same thing can confuse beginners. When to reach for it: when data fits comfortably in memory and needs cleaning, exploring, or summarising in Python; a database or a distributed tool when the data is too big to hold in memory at all.&lt;/p&gt;

&lt;p&gt;Tables, without the spreadsheet&lt;/p&gt;

&lt;p&gt;Pandas is tables in Python, without the spreadsheet: DataFrames you can filter, group, and join, in code that reruns exactly. It trades memory for a workflow that scales past copy and paste, and for data that fits on one machine, that trade is usually worth making.&lt;/p&gt;

&lt;p&gt;Originally published at &lt;a href="https://practicaldevblog.blogspot.com/2026/11/pandas-explained-tables-in-python.html" rel="noopener noreferrer"&gt;https://practicaldevblog.blogspot.com/2026/11/pandas-explained-tables-in-python.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>pandas</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>TensorFlow Explained: Machine Learning, From Tensors to Training</title>
      <dc:creator>The Practical Developer</dc:creator>
      <pubDate>Sat, 31 Oct 2026 20:29:10 +0000</pubDate>
      <link>https://dev.to/practicaldevblog/tensorflow-explained-machine-learning-from-tensors-to-training-lpe</link>
      <guid>https://dev.to/practicaldevblog/tensorflow-explained-machine-learning-from-tensors-to-training-lpe</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Machine learning sounds like magic until you see the machinery: numbers flow through operations, a model adjusts its parameters, and error goes down. TensorFlow, released by Google in 2015, is the library that packages that machinery: it represents data as tensors, multi-dimensional arrays, and gives you the tools to build, train, and ship models, from a laptop experiment to a phone app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tensors, Keras, and the road to production
&lt;/h2&gt;

&lt;p&gt;TensorFlow rests on a few distinctive ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tensors first&lt;/strong&gt;: data is a tensor, an array with shape and type, and every operation, from addition to a neural network layer, works on tensors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keras, the friendly front door&lt;/strong&gt;: the high-level Keras API lets you stack layers into a model in a few lines, while TensorFlow underneath handles the maths.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Eager by default, graphs when needed&lt;/strong&gt;: run operations immediately while experimenting, then compile a model into an efficient graph for training and serving.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An ecosystem around the model&lt;/strong&gt;: TensorFlow Lite runs models on phones, TensorFlow.js runs them in the browser, and serving tools take a trained model into production.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A tiny example shows the shape, a model that learns the line y = 2x + 1 from four examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tensorflow&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;tf&lt;/span&gt;

&lt;span class="n"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;5.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;7.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keras&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sequential&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="n"&gt;tf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keras&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,)),&lt;/span&gt;
    &lt;span class="n"&gt;tf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keras&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Dense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;units&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;optimizer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;sgd&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;loss&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;mean_squared_error&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ys&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;epochs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mf"&gt;4.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float32&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Input(shape=(1,))&lt;/code&gt; says each example is one number, &lt;code&gt;Dense(units=1)&lt;/code&gt; adds a single output neuron, &lt;code&gt;compile&lt;/code&gt; picks the optimiser and the loss, and &lt;code&gt;fit&lt;/code&gt; trains for 100 passes over the data. Predicting for 4.0 gives a value near 9.0, not exactly, because training improves gradually rather than solving the equation outright.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest trade
&lt;/h2&gt;

&lt;p&gt;TensorFlow trades simplicity for scale: it is a large library with a learning curve, small models are often easier in a smaller library like scikit-learn, and debugging a training run takes patience. When to reach for it: for neural networks, especially ones headed for production or mobile; a smaller library when the model is a simple regression or classifier.&lt;/p&gt;

&lt;h2&gt;
  
  
  A model, not magic
&lt;/h2&gt;

&lt;p&gt;TensorFlow is machine learning from tensors to training: data as arrays, models as stacked layers, and an ecosystem that carries a trained model onto phones, browsers, and servers. It trades a gentle learning curve for serious scale, and for neural networks that need to ship, that scale is the reason it endures.&lt;/p&gt;

</description>
      <category>tensorflow</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Playwright Explained: Browser Tests That Act Like a Real User</title>
      <dc:creator>The Practical Developer</dc:creator>
      <pubDate>Sat, 31 Oct 2026 20:27:44 +0000</pubDate>
      <link>https://dev.to/practicaldevblog/playwright-explained-browser-tests-that-act-like-a-real-user-2mo6</link>
      <guid>https://dev.to/practicaldevblog/playwright-explained-browser-tests-that-act-like-a-real-user-2mo6</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Tests that click through a browser used to be flaky: the test clicked before the page was ready, or grabbed the wrong element after a redesign. Playwright, released by Microsoft in 2020, fixes most of that by driving real Chromium, Firefox, and WebKit browsers and waiting for elements to be ready before it acts. It is now a standard choice for end-to-end tests, from a marketing page to a full checkout flow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real browsers, auto-waiting, and locators
&lt;/h2&gt;

&lt;p&gt;Playwright rests on a few distinctive ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real browsers, three engines&lt;/strong&gt;: one API drives Chromium, Firefox, and WebKit, so a test can prove a page works in every engine, not just one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-waiting&lt;/strong&gt;: clicks, fills, and assertions wait for the element to be actionable, which removes most of the sleeps and retries that made older browser tests flaky.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Locators that read like intent&lt;/strong&gt;: find elements by role, label, or text, so tests describe what the user sees instead of fragile CSS paths.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tooling that helps debugging&lt;/strong&gt;: code generation records your clicks into a test, traces replay failures step by step, and screenshots show exactly what the browser saw.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A tiny example shows the shape, a test that loads a page and checks its heading:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@playwright/test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;example page has a heading&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;heading&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Example Domain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})).&lt;/span&gt;&lt;span class="nf"&gt;toBeVisible&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;page.goto&lt;/code&gt; loads the page, &lt;code&gt;getByRole('heading', ...)&lt;/code&gt; finds the heading the way assistive technology would, and &lt;code&gt;toBeVisible&lt;/code&gt; waits for it automatically instead of checking instantly. If the heading appears a moment later, the test still passes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest trade
&lt;/h2&gt;

&lt;p&gt;Playwright trades speed and simplicity for realism: browser tests are slower than unit tests, they need browsers installed, and they can still be flaky around third-party widgets and animations. When to reach for it: for flows that must work in a real browser, like sign-up or checkout; unit tests for logic, and API tests for backends, where a browser adds nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test what the user sees
&lt;/h2&gt;

&lt;p&gt;Playwright is browser tests that act like a real user: real engines, auto-waiting, and locators that describe intent, in tests that read like a visitor's journey. It trades test speed for confidence in the real thing, and for the flows that must not break, that confidence is worth the wait.&lt;/p&gt;

</description>
      <category>playwright</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Ruby on Rails Explained: Web Apps by Convention, Not Configuration</title>
      <dc:creator>The Practical Developer</dc:creator>
      <pubDate>Sat, 31 Oct 2026 20:26:02 +0000</pubDate>
      <link>https://dev.to/practicaldevblog/ruby-on-rails-explained-web-apps-by-convention-not-configuration-5h3e</link>
      <guid>https://dev.to/practicaldevblog/ruby-on-rails-explained-web-apps-by-convention-not-configuration-5h3e</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Most web frameworks give you pieces and ask you to wire them together. Ruby on Rails, released in 2004 by David Heinemeier Hansson from the Basecamp codebase, gives you the whole app structure up front: where models live, how URLs map to code, and how database tables become objects. That opinionated structure is the point. Follow the conventions and a small team can ship a complete web app, database, pages, forms, and email, in days rather than weeks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Convention over configuration, MVC, and Active Record
&lt;/h2&gt;

&lt;p&gt;Rails rests on a few distinctive ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Convention over configuration&lt;/strong&gt;: file names, class names, and table names follow patterns, so Rails can guess what you mean instead of asking you to spell it out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MVC, built in&lt;/strong&gt;: models hold data and rules, controllers handle requests, views render pages, and the three have a fixed home in every Rails app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Active Record&lt;/strong&gt;: a database table becomes a class, a row becomes an object, and queries read like plain Ruby instead of SQL strings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Everything in one box&lt;/strong&gt;: routing, database migrations, form helpers, background jobs, and mailers ship together, so a new app needs few extra decisions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A tiny example shows the shape, an articles listing built from three small files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# config/routes.rb&lt;/span&gt;
&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;draw&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:articles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:show&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# app/models/article.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Article&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;validates&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;presence: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# app/controllers/articles_controller.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ArticlesController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
    &lt;span class="vi"&gt;@articles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;resources :articles&lt;/code&gt; creates the routes for listing and showing articles, &lt;code&gt;validates :title, presence: true&lt;/code&gt; makes a title required, and &lt;code&gt;Article.all&lt;/code&gt; returns every row as an object. The view then loops over &lt;code&gt;@articles&lt;/code&gt; and renders each one. Naming does most of the work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest trade
&lt;/h2&gt;

&lt;p&gt;Rails trades flexibility and raw speed for speed of development: its conventions feel restrictive when an app outgrows them, its "magic" can hide what is happening until something breaks, and very high traffic apps often need careful tuning. When to reach for it: when building a database-backed web app quickly with a small team; a lighter framework or a different language when the app is unusual enough that the conventions fight you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conventions that ship
&lt;/h2&gt;

&lt;p&gt;Ruby on Rails is web apps by convention, not configuration: MVC structure, Active Record models, and a full toolbox in one framework, in a language that reads like plain English. It trades some freedom for shipping speed, and for teams that want a working app this week, that trade is the whole appeal.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Objective-C Explained: The Language That Built the iPhone Era</title>
      <dc:creator>The Practical Developer</dc:creator>
      <pubDate>Fri, 30 Oct 2026 13:18:45 +0000</pubDate>
      <link>https://dev.to/practicaldevblog/objective-c-explained-the-language-that-built-the-iphone-era-55g7</link>
      <guid>https://dev.to/practicaldevblog/objective-c-explained-the-language-that-built-the-iphone-era-55g7</guid>
      <description>&lt;p&gt;Introduction: Before Swift, every iPhone app was written in Objective-C. Created in the 1980s by adding Smalltalk-style messaging to C, it became Apple's language through NeXT, macOS, and the first decade of iOS, and it still underpins much of Apple's older code. Its syntax looks strange at first, with square brackets and colons where other languages use dots, but that strangeness is its central idea: objects do not call methods, they send messages, and the runtime decides what happens next.&lt;/p&gt;

&lt;p&gt;Messages, the runtime, and Cocoa: Message syntax: instead of object.method(argument), you write [object method:argument], and a method with several parts reads like a sentence, with each argument labelled. A dynamic runtime: messages are resolved at run time, so objects can forward messages, add methods, or respond in ways the compiler never saw, which powers much of Cocoa's flexibility. C underneath: Objective-C is a strict superset of C, so C code, pointers, and libraries work unchanged inside an Objective-C program. Cocoa frameworks: AppKit on macOS and UIKit on iOS, built on Objective-C, gave developers the windows, views, and controls that defined Apple software for decades.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight objective_c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#import &amp;lt;Foundation/Foundation.h&amp;gt;
&lt;/span&gt;&lt;span class="k"&gt;@interface&lt;/span&gt; &lt;span class="nc"&gt;Greeter&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;NSObject&lt;/span&gt;
&lt;span class="k"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;:(&lt;/span&gt;&lt;span class="n"&gt;NSString&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@end&lt;/span&gt;
&lt;span class="k"&gt;@implementation&lt;/span&gt; &lt;span class="nc"&gt;Greeter&lt;/span&gt;
&lt;span class="k"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;:(&lt;/span&gt;&lt;span class="n"&gt;NSString&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="n"&gt;NSLog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"Hello, %@!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;@end&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;@autoreleasepool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="n"&gt;Greeter&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;greeter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;Greeter&lt;/span&gt; &lt;span class="nf"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;greeter&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;@"Ayesha"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation: &lt;a class="mentioned-user" href="https://dev.to/interface"&gt;@interface&lt;/a&gt; declares the class, @implementation defines it, NSLog prints with %@ for an object, and [greeter greet:@"Ayesha"] sends the greet message with its labelled argument. The brackets are the language.&lt;/p&gt;

&lt;p&gt;The honest trade: Objective-C's trade is modernity and hiring: Swift is now Apple's preferred language, new projects rarely start in Objective-C, and its syntax and manual memory history (now mostly handled by ARC) feel dated to newcomers.&lt;/p&gt;

&lt;p&gt;When to reach for it: when maintaining or extending existing Apple codebases, where it is still essential; Swift for any new Apple project, where the tooling and community have moved.&lt;/p&gt;

&lt;p&gt;The brackets that built an era: Objective-C is the language that built the iPhone era: C with Smalltalk messaging, a dynamic runtime, and Cocoa, in syntax that reads like sentences in square brackets. It trades modern tooling for history and depth, and for the codebases it still powers, that history is unavoidable.&lt;/p&gt;

</description>
      <category>objectivec</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Lua Explained: The Tiny Language Behind Big Games</title>
      <dc:creator>The Practical Developer</dc:creator>
      <pubDate>Fri, 30 Oct 2026 13:16:56 +0000</pubDate>
      <link>https://dev.to/practicaldevblog/lua-explained-the-tiny-language-behind-big-games-711</link>
      <guid>https://dev.to/practicaldevblog/lua-explained-the-tiny-language-behind-big-games-711</guid>
      <description>&lt;p&gt;Introduction: Some languages want to be the whole program. Lua, created in Brazil in 1993, wants to be the part you script: a tiny, fast language designed to live inside a larger application, where designers and modders can change behaviour without rebuilding the host. It powers game scripting in titles like World of Warcraft and Roblox, configuration in tools like Neovim, and embedded scripting in Redis and NGINX. Lua proves that a language can be small and still run big systems.&lt;/p&gt;

&lt;p&gt;Tables, metatables, and coroutines: Tables do everything: there is one data structure, the table, and it serves as array, record, object, and module, so the language stays tiny while programs stay expressive. Metatables for behaviour: attach a metatable to a table and you can define how it behaves for operators, indexing, and method calls, which is how Lua builds objects without classes. Coroutines: lightweight, cooperative threads that pause and resume, ideal for game logic that needs to wait without blocking the whole program. Embeddable by design: a small C API lets a host program run Lua scripts, expose its own functions to them, and keep the scripting layer separate from the engine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- A table acting as a simple record&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Ayesha"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nc"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_points&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;points&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;add_points&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;-- Ayesha, 10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation: The colon in player:add_points(10) passes player as the first argument, so self is the table itself. One structure, one calling convention, and the object emerges from it.&lt;/p&gt;

&lt;p&gt;The honest trade: Lua's trade is ecosystem and scale: it has fewer libraries than Python or JavaScript, its standard library is deliberately small, and large codebases need discipline to keep table-based designs readable.&lt;/p&gt;

&lt;p&gt;When to reach for it: when you need a fast, embeddable scripting layer inside a game, tool, or server; a full general-purpose language when the program itself, not the scripting layer, is the job.&lt;/p&gt;

&lt;p&gt;Small language, large stage: Lua is the tiny language behind big games: tables, metatables, coroutines, and an embeddable design, in a language that fits inside the programs it scripts. It trades a large standard library for size and speed, and for games and tools that need scripting, that trade is exactly right.&lt;/p&gt;

</description>
      <category>lua</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>MATLAB Explained: Engineering Maths in Matrix Form</title>
      <dc:creator>The Practical Developer</dc:creator>
      <pubDate>Fri, 30 Oct 2026 13:15:59 +0000</pubDate>
      <link>https://dev.to/practicaldevblog/matlab-explained-engineering-maths-in-matrix-form-4jig</link>
      <guid>https://dev.to/practicaldevblog/matlab-explained-engineering-maths-in-matrix-form-4jig</guid>
      <description>&lt;p&gt;Introduction: Most programming languages treat numbers one at a time and add matrices as a library. MATLAB, released in 1984, flips that round: a matrix is the basic value, so adding, multiplying, and plotting whole arrays is the default, not the special case. It grew out of numerical linear algebra, became the standard tool in engineering courses and labs, and still powers signal processing, control systems, and data analysis where the maths, not the software, is the hard part.&lt;/p&gt;

&lt;p&gt;Matrices first, plots in one line, and toolboxes: Everything is a matrix: even a single number is a 1 by 1 matrix, so operations that need loops in other languages apply to whole arrays at once. Vectorised maths: add a vector to a vector, multiply matrices, or solve a linear system with a single operator, and the language handles the element-by-element work. Plotting built in: a plot is one function call, not a charting library to learn, so results are visible immediately. Toolboxes: curated collections for signal processing, control, image processing, and more, each with tested functions for its domain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight matlab"&gt;&lt;code&gt;&lt;span class="c1"&gt;% Solve A*x = b, where A and b are known&lt;/span&gt;
&lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="p"&gt;\&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="c1"&gt;% x is [1; 2], since 1 + 4 = 5 and 3 + 8 = 11&lt;/span&gt;
&lt;span class="c1"&gt;% Plot a sine wave from the same session&lt;/span&gt;
&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nb"&gt;pi&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Sine wave'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation: A backslash b is the backslash operator for solving linear systems, 0:0.1:2*pi builds a range, and sin works on the whole vector at once. No loops, no imports, just maths.&lt;/p&gt;

&lt;p&gt;The honest trade: MATLAB's trade is cost and generality: licences are expensive, the language is a poor fit for general-purpose software or web apps, and code written in MATLAB stays inside its ecosystem unless it is exported.&lt;/p&gt;

&lt;p&gt;When to reach for it: when the job is numerical work, simulation, or analysis, and the toolboxes match the domain; a free language like Python with NumPy when cost or general-purpose code matters more.&lt;/p&gt;

&lt;p&gt;Maths, made visible: MATLAB is engineering maths in matrix form: vectorised operations, one-line plots, and domain toolboxes, in a language where the matrix is the default. It trades general-purpose power and cost for numerical fluency, and for engineers, that fluency is the point.&lt;/p&gt;

</description>
      <category>matlab</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Crystal Explained: Ruby's Syntax, Compiled Speed</title>
      <dc:creator>The Practical Developer</dc:creator>
      <pubDate>Tue, 27 Oct 2026 17:56:37 +0000</pubDate>
      <link>https://dev.to/practicaldevblog/crystal-explained-rubys-syntax-compiled-speed-12j5</link>
      <guid>https://dev.to/practicaldevblog/crystal-explained-rubys-syntax-compiled-speed-12j5</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Ruby is beloved for its readable syntax and developer happiness, and criticised for its speed. Crystal, released in 2014, asks a simple question: what if you kept Ruby's syntax and compiled it to native code? The result is a statically typed, compiled language that reads almost like Ruby, runs close to C speed, and needs no virtual machine. It is still young, but it is the most elegant answer yet to the dynamic-versus-compiled trade-off.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ruby-like syntax, static types, and native compilation
&lt;/h2&gt;

&lt;p&gt;Crystal's model rests on a few distinctive ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ruby-inspired syntax&lt;/strong&gt;: blocks, symbols, and expressive method calls, so Ruby developers feel at home immediately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Static typing with inference&lt;/strong&gt;: types are checked at compile time, but usually inferred, so you get safety without annotating everything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Macros&lt;/strong&gt;: code that writes code at compile time, replacing Ruby's metaprogramming with a safer, checked version of the same power.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native compilation&lt;/strong&gt;: Crystal compiles to a single binary via LLVM, with no runtime to install, so deployment is a file, not a stack.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A tiny example shows the shape: it reads like Ruby, but the compiler checks it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight crystal"&gt;&lt;code&gt;&lt;span class="c1"&gt;# A class with inferred types, compiled to native code&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Greeter&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@name&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;
    &lt;span class="s2"&gt;"Hello, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="no"&gt;Greeter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Ayesha"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;greet&lt;/span&gt;
&lt;span class="c1"&gt;# Hello, Ayesha!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;@name : String&lt;/code&gt; is a typed instance variable; &lt;code&gt;#{@name}&lt;/code&gt; is string interpolation, exactly as in Ruby. Same joy, checked by a compiler, running natively.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest trade
&lt;/h2&gt;

&lt;p&gt;Crystal's trade is youth: a small ecosystem, fewer libraries and jobs than Ruby or Go, and tooling that is still maturing. Windows support has historically lagged, and the community is small. Choose Crystal when you love Ruby's syntax but need compiled speed and single-binary deployment, choose Go when ecosystem and hiring dominate, and choose Ruby when the existing ecosystem matters most.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compiled speed, Ruby syntax
&lt;/h2&gt;

&lt;p&gt;Crystal is Ruby's syntax at compiled speed: inferred static types, macros, and native binaries, in code that reads like Ruby. It trades ecosystem maturity for elegance and performance, and for Rubyists who want speed without leaving home, that trade is tempting.&lt;/p&gt;

&lt;p&gt;Originally published at &lt;a href="https://practicaldevblog.blogspot.com/2026/10/crystal-explained-rubys-syntax-compiled.html" rel="noopener noreferrer"&gt;https://practicaldevblog.blogspot.com/2026/10/crystal-explained-rubys-syntax-compiled.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>crystal</category>
      <category>programming</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Clojure Explained: A Modern Lisp on the JVM</title>
      <dc:creator>The Practical Developer</dc:creator>
      <pubDate>Tue, 27 Oct 2026 17:49:32 +0000</pubDate>
      <link>https://dev.to/practicaldevblog/clojure-explained-a-modern-lisp-on-the-jvm-1o5d</link>
      <guid>https://dev.to/practicaldevblog/clojure-explained-a-modern-lisp-on-the-jvm-1o5d</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Lisp is the second-oldest programming language still in use, and most programmers have never written it, yet its ideas (code as data, functions as values, macros) shaped everything after it. Clojure, released in 2007, is Lisp rebuilt for the modern world: it runs on the JVM, uses every Java library, and replaces Lisp's mutable lists with immutable data structures. It is the language that convinced a generation of sceptics that parentheses are not a problem: they are the point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Immutable data, code as data, and the REPL
&lt;/h2&gt;

&lt;p&gt;Clojure's model rests on a few distinctive ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Immutable data by default&lt;/strong&gt;: maps, vectors, and sets never change in place; "updating" returns a new version, so concurrent code shares data safely and old versions stay available.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code as data&lt;/strong&gt;: Clojure code is itself a data structure (lists), so programs can manipulate programs: macros, the feature other languages fake with code generation, are native.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The REPL&lt;/strong&gt;: develop interactively: evaluate expressions, inspect state, and reshape a running program without restarting it. The REPL is not a toy; it is the workflow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JVM hosted&lt;/strong&gt;: every Java library works, so Clojure programs deploy wherever Java does, with none of the ecosystem risk of a niche runtime.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A tiny example shows the shape: a function, a map, and immutable transformation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="c1"&gt;;; A user, and a function that "ages" them: returning a new map&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;:name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Ayesha"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:age&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;birthday&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:age&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;birthday&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;;; =&amp;gt; {:name "Ayesha" :age 26}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;;; user itself is unchanged: still 25&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No mutation, no classes, just data and functions, and the original value is still there, untouched, for any other code that needs it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest trade
&lt;/h2&gt;

&lt;p&gt;Clojure's trade is familiarity and hiring: parentheses and prefix notation take adjustment, startup time is JVM-slow, and the talent pool is small. Error messages, from the JVM stack, can be cryptic. Choose Clojure when immutable data and interactive development matter most, especially for data pipelines and backends, and choose a mainstream JVM language when team familiarity dominates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lisp, modernised
&lt;/h2&gt;

&lt;p&gt;Clojure is a modern Lisp on the JVM: immutable data, code as data, and REPL-driven development, with every Java library available. It trades familiarity for simplicity that scales, and for programmers who learn it, parentheses stop looking strange and start looking honest.&lt;/p&gt;

&lt;p&gt;Originally published at &lt;a href="https://practicaldevblog.blogspot.com/2026/10/clojure-explained-modern-lisp-on-jvm.html" rel="noopener noreferrer"&gt;https://practicaldevblog.blogspot.com/2026/10/clojure-explained-modern-lisp-on-jvm.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>clojure</category>
      <category>programming</category>
      <category>beginners</category>
      <category>functional</category>
    </item>
    <item>
      <title>R Explained: The Language That Thinks in Data</title>
      <dc:creator>The Practical Developer</dc:creator>
      <pubDate>Tue, 27 Oct 2026 17:47:33 +0000</pubDate>
      <link>https://dev.to/practicaldevblog/r-explained-the-language-that-thinks-in-data-3p43</link>
      <guid>https://dev.to/practicaldevblog/r-explained-the-language-that-thinks-in-data-3p43</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Python does data science well, but R was born for it: created in 1993 by statisticians at the University of Auckland, it thinks in vectors, tables, and distributions the way other languages think in loops and objects. It powers academic research, clinical trials, and data journalism, and its superpower is that the things data people do all day (summarise, filter, plot) are one-liners, not library calls. If your work is data first and software second, R speaks your language natively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vectors, data frames, and the tidyverse
&lt;/h2&gt;

&lt;p&gt;R's model rests on a few distinctive ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vectors everywhere&lt;/strong&gt;: the basic unit is a vector, not a single value, so operations apply to whole columns at once: add 1 to a vector and every element grows, no loop needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data frames&lt;/strong&gt;: tables with named columns are a native type, not an add-on, so datasets feel like the language's home turf.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vectorised statistics&lt;/strong&gt;: means, models, and distributions are built in, from &lt;code&gt;mean()&lt;/code&gt; to linear regression in one function call.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The tidyverse&lt;/strong&gt;: a coherent family of packages (&lt;code&gt;dplyr&lt;/code&gt; for manipulation, &lt;code&gt;ggplot2&lt;/code&gt; for plots) that turned R from a statistics tool into a full data workflow, with readable pipe-based code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A tiny example shows the shape: filter, summarise, and plot-ready, in a few lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="c1"&gt;# A data frame of exam scores&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data.frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;c&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Ayesha"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bilal"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Chen"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;c&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;88&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;95&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;# Mean score, and the top scorer, with no loops&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="c1"&gt;# 85&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="c1"&gt;# Ayesha and Chen&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;$&lt;/code&gt; reaches a column, &lt;code&gt;[rows, ]&lt;/code&gt; filters it, and the whole dataset is one object. That is R's worldview: data first, code second.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest trade
&lt;/h2&gt;

&lt;p&gt;R's trade is generality and speed: it is slower than Python for heavy computation, weaker for general-purpose software, and its syntax quirks (multiple assignment styles, inconsistent naming) confuse newcomers. Choose R when statistics, analysis, and publication-quality plots are the job, and choose Python when the job spans data, apps, and production systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thinks in data
&lt;/h2&gt;

&lt;p&gt;R is the language that thinks in data: vectors, data frames, and vectorised statistics, with the tidyverse turning analysis into readable pipelines. It trades general-purpose power for data-native fluency, and for analysts, that fluency is everything.&lt;/p&gt;

&lt;p&gt;Originally published at &lt;a href="https://practicaldevblog.blogspot.com/2026/10/r-explained-language-that-thinks-in-data.html" rel="noopener noreferrer"&gt;https://practicaldevblog.blogspot.com/2026/10/r-explained-language-that-thinks-in-data.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rstats</category>
      <category>programming</category>
      <category>beginners</category>
      <category>datascience</category>
    </item>
  </channel>
</rss>
