ProgrammingPro #25: Code your own AI Assistant, Java 21 LTS, Python Concurrency, and SBOMs
Bite-sized actionable content, practical tutorials, and resources for programmers.
A good programming language should, like oil paint, make it easy to change your mind.
— Paul Graham (2003), Hackers and Painters
Welcome to this week’s issue of our programmer focused newsletter.
Today, we talk about SBOMs and which format would work best for you. We are also looking at two significant releases, Java 21 LTS and Next.js 13.5's which promise significant performance boosts.
Also, did you know that the secret to more secure AI could lie inside the human brain? And don’t miss an insightful interview with the creator of C++ Bjarne Stroustrup who has some sage advice for upcoming developers.
Our knowledge packed learning guides and resources cover a great wealth of things but here are my top 5 picks:
The easy way to concurrency and parallelism with Python stdlib
🎥Code Your Own AI Assistant with GPT-4 API + LangChain + NLP
🎥Build AI Apps with ChatGPT, Dall-E and GPT-4 using JavaScript
We also have an exclusive excerpt for you from Layered Design for Ruby on Rails Applications from the Packt community. So scroll down and dive right in!
If you want us to find a tutorial for you the next time do let us know by taking our survey and as a bonus you can download a free PDF of the Expert Python Programming eBook upon completion. Your feedback is important for us to ensure this newsletter continues to deliver the most value to you.
Stay awesome!
Divya Anne Selvaraj
Editor-in-Chief
🗞️News, 💡Opinions, and 🔎Analysis
🌚Java 21, the Next LTS Release, Delivers Virtual Threads, Record Patterns and Pattern Matching: Oracle has unveiled Java 21, the latest LTS version of the programming language, featuring 15 Java Enhancement Proposals (JEPs). Notably, this release includes the transition of Virtual Threads from preview to a fully-fledged feature, promising enhanced performance for thread-intensive applications. Additionally, Record Patterns and Pattern Matching for switch have been finalized, strengthening the language-level capabilities for developers. Unnamed Patterns and Variables have also been introduced, streamlining code, and the Vector API continues to evolve for numerically intensive tasks. Looking ahead, JDK 22 is in the pipeline with a targeted release date of March 19, 2024.
When only one SBOM will do, consider these formats: The rise of software bill of materials (SBOM) in software security and compliance is relatively recent, driven by governmental requirements and open-source software expansion. In this article three primary SBOM formats: SPDX, CDX, and SWID are examined. For a more in-depth look at each format's attributes and uses, click through to the full article.
🌚Next.js 13.5 delivers 22% faster startup and optimized package imports: These performance gains were achieved through caching, optimizing file system operations, and efficient tree traversal. Notably, package imports are now automatically optimized. IPv6 hostname support, draft mode in Middleware and Edge Runtimes, and a Playwright test mode are also part of this substantial update. For an exhaustive list of improvements and bug fixes, explore the release notes.
Why I quit opensource: The author of this post draws from personal experience and suggests that quitting open source maybe a healthy solution to avoid burnout. The article emphasizes the challenges faced by maintainers, such as dealing with toxic comments, managing contributions, and the complexity of tooling.
How Instagram scaled to 14 million users with only 3 engineers: They adhered to three core principles: simplicity, avoiding reinventing the wheel, and using proven technologies. Their tech stack included AWS with EC2 for infrastructure, Django written in Python for the backend, and sharded Postgres for data storage. Read to learn more about their streamlined approach which helped Instagram scale to 14 million users in a year, a remarkable feat for a small engineering team.
🎥An Interview With the Creator of C++ - Bjarne Stroustrup: In this very interesting video conversation, Stroustrup touches on what getting into programming means in today’s context and wraps up with his tough but valuable and wise advice to developers.
Brain inspires more robust AI: How can AI-based systems be safeguarded from deceptive inputs? Ukita and Ohki, researchers at the University of Tokyo, have taken inspiration from the human brain to enhance artificial neural networks’ (ANNs) resilience. Their work highlights the ongoing need for innovation to protect AI systems from evolving threats. Learn more in the full article.
🎓 Tutorials and Guides🤓
🎥Vector Embeddings Tutorial – Code Your Own AI Assistant with GPT-4 API + LangChain + NLP: In this solid video course by Ania Kubow, you'll explore the world of vector embeddings, which transform words and items into numerical representations. These embeddings, like magic, enable machines to grasp semantics and relationships between words. From foundational understanding to practical applications, the course covers it all, including creating custom text embeddings using the OpenAI API and building your very own AI Assistant.
Python Try / Except - How to Catch Errors (With Examples): For larger Python projects, error handling isn't just about avoiding crashes; it's about maintaining the program's flow, ensuring it keeps running smoothly even when errors strike. Read this article if you want to learn how to handle various exceptions similarly, but also want to avoid over catching or mishandling exceptions.
Use Cases for IIFEs in JavaScript and Typescript: Immediately Invoked Function Expressions might seem puzzling at first, but they can be handy when bundling utility functions in a library to avoid excessive imports. Read to learn how you can use IIFEs to keep the code clean and concise, especially when dealing with varying data formats.
Why does Python Code Run Faster in a Function?: Local variables are stored in a fixed-size array in a function, allowing for quick and efficient variable retrieval through index-based lookup. In contrast, global variables are stored in a dictionary, requiring a hash table lookup, which is inherently slower. Read to learn how benchmarking and profiling tools can help analyze and optimize Python code for improved performance, and more.
2 Lines Of Code and3 C++17 Features - The overload Pattern: Read this article to unlock the potential of the C++ overload pattern which simplifies std::variant visitation, evolving from C++17 to C++20 and C++23. In C++23, this pattern gains safety.
🎥Build AI Apps with ChatGPT, Dall-E and GPT-4 using JavaScript: This free to access, 4-hour, 33-minute video course with 74 lessons, led by Tom Chant, will teach you to explore the capabilities of OpenAI through hands-on projects. You'll start by creating a movie pitch generator, but move on to doing a lot more. Along the way, you'll acquire skills in Firebase database management and API key security.
🎥Full Stack with React and Appwrite: This free to access video course led by Colby Fayock, will guide you through the essential components of building web applications. By the end you'll master data management using Appwrite in your React app, including database operations and user management. The course is designed for a full-stack experience, starting with a pre-built UI to kickstart your development journey.
Cache Line Alignment in C++ — How It Makes Your Program Faster: In a practical example, without cache line alignment, a program takes 518.364 ms, but with alignment, it improves to 265.304 ms. So, why should you care? Cache line alignment can significantly boost your program's speed, especially as more cores access data in the same cache line. Dive deeper for optimization insights.
C# Threading and Multithreading: A Guide With Examples: This guide explores threading in C#, emphasizing the benefits of multithreading for application efficiency and responsiveness. It provides guidance on when to use single threading or multithreading, along with best practices like async/await, thread safety, and more.
Leveraging Rust in a high-performance Java database: This article explores the journey of incorporating Rust into QuestDB’s (a high-performance time-series database primarily written in Java and C++) codebase and highlights key aspects such as zero-GC Java, Rust build integration with Maven, and the use of JNI for seamless interaction between Rust and Java. Read to learn about the challenges they faced when considering other languages and the benefits Rust offers in terms of GC-free dependencies and symbol collision prevention.
Bringing more sweetness to Ruby with Sorbet types: Sorbet, a gem developed by Stripe, introduces type checking through the concept of gradual typing. Unlike Ruby 3's approach, Sorbet provides robust tools for code intelligence. Read to learn more about Sorbet's capabilities and how to set it up in your Ruby project.
Quick CMake tutorial: This tutorial provides a step-by-step guide on creating and developing a simple CMake project in CLion. Whether you're a beginner or want to refresh your CMake knowledge, this tutorial has you covered.
🧠 Expert insights from the Packt Community📚
An exclusive excerpt from Chapter 2, Active Models and Records in the book Layered Design for Ruby on Rails Applications by Vladimir Dementyev.
Seeking God objects
Active Record is the largest part of Rails; its code base contains twice as many files(over 1,000) and lines of code (over 100,000) as the second largest, which is Action Pack. With that amount of machinery under the hood, it provides dozens of APIs for developers to use in their applications. As a result, models inherited from Active Record tend to carry many responsibilities, which we were trying to enumerate in the previous sections of this chapter. Such over-responsible Ruby classes are usually referred to as God objects.
From the code perspective, a lot of responsibility means a lot of lines of source code. The number of lines itself can’t be considered an indicator of unhealthy code. We need better metrics to identify good candidates for refactoring in our codebase. The combination of churn and complexity has been proven to be such indicators.
Churn describes how often a given file has been modified. A high change rate could indicate a code design flaw: either we’re adding new responsibilities or trying to eliminate the shortcomings of the initial implementation. Let’s see how we can obtain the churn factor.
Today, every project uses a version control system; thus, we can calculate a given file’s churn as the total number of commits where the file has been affected. With Git, the following command returns the churn factor for the User model:
$ git log --format=oneline-- app/models/user.rb | wc -l
408
We can go further and use the power of Unix commands to get the top-10 files according to churn:
find app/models -name"*.rb" | while read file; do echo $file `git log -–format=oneline --$file | wc -l`; done | sort -k 2 -nr | head
Depending on the project age, you might want to limit the commit date range (by using the --since option).
With regard to complexity, there is no single algorithm for code complexity to calculate the corresponding metrics. In Ruby, a tool called Flog (https://github.com/seattlerb/flog) is the de facto instrument to calculate source code complexity.
This is how we can get the overall complexity for a single file:
$ flog -sapp/models/user.rb
274.3: flog total
8.1: flog/method average
I will leave you to devise a Unix one-liner to get the top-N most complex source files in the project.
Armed with these two metrics, churn and complexity, we can now define the rule of thumb for identifying Ruby classes that deserve the most refactoring attention. Usually, the churn * complexity product is used as a cumulative metric. Still, for simplicity, we can say that the intersection of the top-10 lists for churn and complexity is the starting set.
What a gem – attractor
Attractor (https://github.com/julianrubisch/attractor) is a code complexity calculation and visualization tool. It calculates both churn and complexity (using Flog)for you and provides an interactive web interface to analyze the collected data. It supports Ruby and JavaScript, thus being a complete solution for Rails web applications.
In Ruby on Rails projects, the most complex class, according to the cumulative value, would likely be one of your core models: user, account, project, or similar. These are typical God object names.
There is no one-size-fits-all solution to return such objects from heaven to earth, but the strategy described in this book (extracting abstraction layers) will help you keep your objects’ feet on the ground.
Layered Design for Ruby on Rails Applications by Vladimir Dementyev was released in August, 2023. To get a more comprehensive preview of the book's contents, read the first chapter available for free and buy the book here or signup for a 7-day free trial to access the complete book and the entire Packt digital library. To explore more, click on the button below.
🔑 Secret Knowledge: Learning Resources🔬
The easy way to concurrency and parallelism with Python stdlib: This article emphasizes the practicality of using Python’s standard library and the importance of understanding when and where to apply Python’s tools most effectively. For example, by using ThreadPoolExecutor or ProcessPoolExecutor, developers can easily distribute work to multiple threads or processes, improving efficiency in tasks that don't require complex solutions. These tools are particularly valuable for I/O-bound tasks, non-CPU-bound operations, and scenarios where data sharing or true parallelism is needed.
Python variables, references and mutability: Everything in Python is passed "by reference," meaning variables point to the same object. You can check if two variables reference the same object using ‘is’. Mutability comes into play with objects like lists (mutable) and strings (immutable). Modifying a list affects all references to it, while modifying an immutable object creates a new object. Read to understand these crucial concepts to avoid unexpected behavior in Python.
60 Top AI Code Generation Tools: Here’s a list of some of the best AI tools for code generation along with an AI-powered search box to find the best tools for your task.
Trivial infinite loops in C++ are not Undefined Behavior: While C does not consider iteration statements with constant expressions as Undefined Behavior, C++ does. This distinction can lead to issues in low-level programming when using infinite loops, as C++ compilers may optimize them away, causing unexpected behavior. This proposal suggests aligning C++ with C in this regard to allow for idiomatic trivial infinite loops without Undefined Behavior.
C# exception handling vs. Java: In Java, exceptions are "checked" by the compiler, forcing methods to declare what exceptions they can throw, leading to better error recovery and code stability. However, in C#, methods don't declare the exceptions they can throw, making it challenging to anticipate and recover from errors effectively. Read for a detailed understanding of this issue and a real-life example.
Dynamic Memory Allocation in C using malloc(), calloc(), free() and realloc(): Discover how these functions let you adapt your memory needs during runtime, from allocating memory to freeing it and even resizing. Dive into included code examples for a deeper understanding.
🎥I Tried To Write an Object-Oriented Program in a Non-OOP Language (Golang): In Go, which doesn't support classical inheritance, crafting an adventure game might seem challenging for those accustomed to object-oriented languages like Java or C#. However, in this video tutorial, the presenter demonstrates a clever workaround for creating what resembles a 'class hierarchy' in Go.
Java21's pattern matching could actually convince me to touch Java again: Java is now capable of expressing algebraic data types, a fundamental concept in functional programming. This development aligns Java more closely with languages like Kotlin, Rust, and C#. Read to learn how these changes will make data processing more efficient in Java.
So, What's So Special About The Mill Scala Build Tool?: Beyond surface debates, what truly matters in a build tool is how it answers complex questions effortlessly. The author of this article claims that Mill accomplishes this, making it a standout choice in the realm of Scala build tools, trusted by projects like Coursier and Scala-CLI. Read to learn more about how Mill seamlessly integrates with your programming knowledge, offering enjoyable configuration and maintenance ease.
Troubleshooting common PHP debugging issues in PhpStorm:.From collecting debugging logs to troubleshooting debugger connection problems, this guide can be your troubleshooting compass.
Deno by example: This resource comprises a set of annotated instances illustrating the utilization of Deno and its diverse feature set. It serves as both a reference for executing tasks in Deno and a valuable tutorial for comprehending the wide array of features Deno offers.
🛠️ HackerHub: Tools & Launches⚒️
refactor: a toolkit that provides a dependency-free, AST-based approach for source code refactoring, with a focus on simple yet effective transformations like replacing the "placeholder" identifier with "42" in Python code.
Vely: a high-performance, open-source framework designed for web applications and various other tasks, built entirely in C for efficiency and safety, offering a unique approach to code refactoring and development.
ghidra: a robust software reverse engineering framework by the National Security Agency (NSA), offering versatile tools for analyzing compiled code on diverse platforms, including disassembly, decompilation, scripting, and more, with extensive customization options.
free-for-dev: a curated list of software and services, primarily aimed at infrastructure developers, that offer free tiers for developers, encompassing various categories such as cloud providers, analytics, APIs, code quality, and more.
trpc: a technology that enables easy creation and consumption of fully type-safe APIs without schemas or code generation, featuring full static type safety on the client, no code generation, and support for various adapters like React.js and Next.js.
📢 If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want to advertise with us.
We have an entire range of newsletters with focused content for tech pros. Subscribe to the ones you find the most useful here. Complete ProgrammingPro archives can be found here.
If you have any comments or feedback, take the survey.



