How My Python Brain Almost Broke My Rust Code🐍🦀 "I typed return, added a semicolon, and Rust looked at me like I’d just tried to put ketchup on a five-star steak." Coming from Python, we’re treated to a world where functions are like polite requests: "Please do this, and return this value when you're done." It’s explicit. It’s comfortable. It’s what we know. But then I met Rust. I tried to write a simple area function and my Python instincts screamed: “Declare the variables! Use the keyword! End the line!” The result? A syntax error that felt like a personal intervention. ## Under the Hood: The "Semicolon" Secret 🤐 In Python, almost everything is a statement. A statement is a command—it does something. In Rust, the magic lies in Expressions. With a semicolon (;): You’ve created a Statement. It performs an action, returns "unit" (), and effectively "kills" the value's journey. Without a semicolon: You’ve created an Expression. The value is "live," and because it’s the last thing in the block, Rust "yields" it upward to the function caller. You may ask? Why does Rust hate my return 🤷? It doesn't! You can use return, but idiomatic Rust treats the last expression as the "final result" of the block. Think of a Python function as a vending machine (you have to press a button to get the result out). Think of a Rust function as a waterfall (the value naturally flows out the bottom unless you put a dam—a semicolon—in its way). I wanna spoil your evening dear python Devs who are transitioning 🤣: 1. Stop declaring "Return variables": You don't need result = x * y. Just let x * y be the last line. 2. The Semicolon is a Wall: If you want a value to leave a function, don't block it with a ;. 3. Types are Friends: While Python guesses what you’re returning, Rust demands you sign a contract by declaring the return type before you even type the type the logic 🫣 eg.(-> i32) . It feels strict and very manual, but it’s actually Rust’s way of promising your code won't crash at 3 AM 😂. Conclusion: Transitioning from Python to Rust isn't just about learning new syntax; it’s about moving from a "Command" mindset to a "Flow" mindset. Python tells the computer what to do; Rust describes how data should transform brick by brick. Ditch the semicolon, ditch the indentation,embrace the expression, and let your code flow! 🦀✨ #RustLang #Python #CodingHumor #SoftwareEngineering #LearnInPublic
Prince Jerry Essien’s Post
More Relevant Posts
-
🐍 Coming from Python. Last week I confidently wrote this in Rust: for i in range(1..100) { // 💥 sum += i; } Error: cannot find function 'range' in this scope My brain: “But Rust it’s just Python with semicolons?” That tiny mistake became one of the best lessons I’ve had in systems programming. 🔍 Corrected Rust vs Python Rust fn main() { let number: u32 = 92; if number % 2 == 0 { println!("{} is even", number); } else { println!("{} is odd", number); } let size = match number { 1..=20 => "small", 21..=50 => "medium", 51..=100 => "large", _ => "out of range", }; let mut sum = 0; for i in 1..=100 { sum += i; } println!("Sum = {}", sum); } Python number = 92 if number % 2 == 0: print(f"{number} is even") else: print(f"{number} is odd") if 1 <= number <= 20: size = "small" elif 21 <= number <= 50: size = "medium" elif 51 <= number <= 100: size = "large" else: size = "out of range" total = sum(range(1, 101)) print(f"Sum = {total}") Both do the same job. But the how is completely different. 🧠 Under the Hood – What Rust Forces You to Respect 1. No hidden pointers Python’s number = 92 is a full PyObject on the heap (refcount + type pointer + value). Rust’s u32 lives on the stack one CPU register. Modulo is a single instruction. 2. Zero-cost abstractions Rust’s 1..=20 in match compiles to two integer comparisons (disappears after optimization). No method calls, no temporary objects. 3. The loop reality Rust’s 1..=100 iterator lives entirely on the stack. 100 stack increments. Python’s range(1, 101)creates 100 Python integer objects behind the scenes (heap + refcounting + GC pressure). 4. Match is lightning fast Rust turns match into a jump table or optimized branches. Python’s version (even structural pattern matching) still has runtime overhead. ⚡ The Discipline Rust Teaches Python lets you be productive. Rust forces you to be precise. No more `range()` → Use the `..` syntax directly. Forgetting `mut`? Compiler stops you. Semicolon on last expression? You just returned `()`. This explicitness about memory and ownership is exactly why Rust code is so reliable and fast. Pro tips for Python devs: Treat the compiler like a strict but honest mentor. Understand stack vs heap early — it makes ownership click. Run `cargo clippy` religiously. 💬 Final Thought Rust won’t let you forget that every variable occupies real memory, every loop touches real silicon, and every decision has consequences. Python is a fantastic friend. Rust is a disciplined mentor that makes you a better programmer. Your Python experience is an advantage once you unlearn a few habits. Like ❤️ if you’ve ever tried to use Python syntax in Rust Repost 🔁 to help other Pythonistas Comment💬: What Python habit was hardest for you to break in Rust? #RustLang #Python #RustForPythonDevs
To view or add a comment, sign in
-
-
Most Python code works. That’s not the problem. The problem is - most of it doesn’t scale past the person who wrote it. You’ve probably seen code like this: • full of comments explaining what’s happening • try/finally blocks everywhere • repeated logic for caching, logging, auth • functions doing 5 things at once It works. Until it doesn’t. The shift that changed how I think about Python: 👉 Stop writing logic 👉 Start using language-level patterns Once you start seeing it this way: • with replaces cleanup logic • decorators replace repeated behavior • generators replace unnecessary data structures • dunder methods make your objects feel native The result? Code that explains itself without comments, removes entire classes of bugs, and actually scales across teams. I wrote a deep dive on this - not surface-level tips, but how these patterns actually work, when to use them, and how they reshape your code. 👉 Read the full article: https://lnkd.in/g_9GZDRk Curious — what’s one Python concept that only clicked after real-world experience? For me, it was realizing generators aren’t about syntax - they’re about thinking in streams instead of collections. #Python #CleanCode #SoftwareEngineering #ScalableSystems #DesignPatterns #AdvancedPython #BackendDevelopment
To view or add a comment, sign in
-
Python may get async yield from. Nice syntax. Potentially ugly consequences. At first glance, it feels like a natural extension of yield from for async generators. It is convenient. It is visually consistent. And yes, sometimes it would make code cleaner. But async generators are already one of those Python features that look simpler than they really are. Go a bit deeper, and you run into things like explicit closing, cleanup that does not happen when you expect, wrong assumptions about generator behavior, dependence on an event loop just to finish safely, and bugs that appear the moment multiple tasks touch the same flow. That is the real discussion. Not whether async yield from looks elegant. But whether it makes a sharp edge even sharper. This is one of the things I find most interesting in Python: a feature can look like syntax sugar on the surface, while quietly expanding the state model underneath. And in production systems, that difference matters. Complexity in Python rarely arrives as one dramatic failure. It shows up as a chain of locally reasonable decisions that slowly become hard to reason about as a whole. That is why async-heavy systems need more than code that “works”. They need clear lifecycle rules, ownership boundaries, and predictable behavior under failure. Curious where others land on this: Would async yield from make async Python better, or just easier to misuse?
To view or add a comment, sign in
-
Lambda functions are one of those Python features that look strange at first but become second nature once you understand when and why to use them. They are not meant to replace regular functions. They are meant to complement them — providing a clean, concise way to define simple operations right where you need them, without the overhead of a full function definition. Once you start seeing lambda in map(), filter(), sorted(), and pandas apply() and using it naturally yourself — your Python code becomes noticeably cleaner and more expressive. Start simple. Practice with sort keys and map() transformations. Then bring them into your data science workflow and watch how naturally they fit. Read the full post here: https://lnkd.in/ergQmrXP #Python #DataScience #Programming #Pandas #Analytics #DataEngineering
To view or add a comment, sign in
-
🔸 🔸 🔸 Classic example to address late-binding and closures in python This 4 line of code talks about multiple important concepts ↘️ Code: funcs = [] for i in range(3): funcs.append(lambda : i) print([f() for f in funcs]) 🤔 What do you think ❓ Will it give any result, will it error out of random ❓ 🟰 Well, this prints [2,2,2] over console The idea is to demystify why this code does what it does under the hood. Concepts ↘️ ➡️ Is lambda : i a valid syntax ? If yes, what does it denote It denotes a shorthand notation to define a function that does not accept any input parameters and returns a single value as output. What will lambda : i resolve to ❓ ↘️ def f(): return i ❓ What is the iterative statement doing 🟰 It simply creates a container in memory, denoted by i. Initializes i to 0 and keeps incrementing the value that the container referenced by i contains ➡️ i : 0 -> 1 -> 2 ❓What will the list funcs hold ➡️ It's important to note here, funcs is a list that appends lambda into it. ➡️ Since, lambda is nothing more than a function in python, the list holds function ✅ ❓ But, how can a list hold function and what does it mean ➡️ Python treats function as objects, and in programming objects are nothing more than a memory address. 🟰 So, the funcs list holds memory addresses that individually resolve to functions denoted by lambda ✅ ➡️ Another important pointer to note here , the list holds the memory reference to these functions, not the actual value returned by the function. ✅ ❓ Demistify [f() for f in funcs] 🟰 This is a list comprehension in python. ➡️ We are iterating over all thats contained in the list, referencing each element via local variable f Since, f refers to an in-memory function, f() will simply invoke the function call. ✅ ➡️ When i = 0: Invoke f(), the first function pointed to by the first element of the list funcs ❓ The interesting part Function call always creates a new individual scope in python. You can say it as a standalone local environment specific to that function call. So, for the first element in funcs f() -> invokes a function that returns i ❓ Where is i now ➡️ Well, i comes from the loop scope created earlier and is used in the enclosed scope lambda : i denoted by function. ❓ So , are we talking about a closure concept in python here ? ➡️ Yes, this is a closure as lambda is closing over the variable i which is defined in the outer scope, the outer scope is the loop scope. ❓ Another interesting thing to note here is : ➡️ i is defined over a single outer scope, so it is shared amongst all the functions contained in the list funcs. 🤔 Think of it as : We are evaluating each function in the list funcs, where each function simply returns i. 🟰 The value of i = 2, post loop iteration finished in range(3), and hence each of these function calls will return the value 2 i.e. value of the variable closed over by lambda. #python #closure #lambda #softwareengineering #dataengineering
To view or add a comment, sign in
-
🔥 How Python Really Loads Modules (Deep Internals) Every time you write `import math` Python doesn't blindly re-import it. It follows a smart 4-step pipeline under the hood. Here's exactly what happens 👇 ━━━━━━━━━━━━━━━━━━━━ 𝗦𝘁𝗲𝗽 𝟭 — Check the cache first ━━━━━━━━━━━━━━━━━━━━ Python checks sys.modules before doing anything else. If the module is already there → it reuses it. No reload, no wasted work. That's why importing the same module 10 times in your code doesn't slow anything down. ━━━━━━━━━━━━━━━━━━━━ 𝗦𝘁𝗲𝗽 𝟮 — Find the module ━━━━━━━━━━━━━━━━━━━━ If not cached, Python searches in order: → Current directory → Built-in modules → Installed packages (site-packages) → All paths in sys.path This is why path order matters when you have naming conflicts. ━━━━━━━━━━━━━━━━━━━━ 𝗦𝘁𝗲𝗽 𝟯 — Compile to bytecode ━━━━━━━━━━━━━━━━━━━━ Your .py file gets compiled into bytecode (.pyc) and stored inside __pycache__/ Next time? Python skips compilation if the source hasn't changed. Faster startup. ━━━━━━━━━━━━━━━━━━━━ 𝗦𝘁𝗲𝗽 𝟰 — Execute and register ━━━━━━━━━━━━━━━━━━━━ Python runs the module code, creates a module object, and adds it to sys.modules["module_name"] Now it's cached for every future import in the same session. ━━━━━━━━━━━━━━━━━━━━ Most devs just write `import x` and move on. But knowing this pipeline helps you: ✅ Debug mysterious import errors ✅ Understand why edits don't reflect without reloading ✅ Write faster, cleaner Python What Python internals have surprised you the most? Drop it below 👇 #Python #Programming #SoftwareEngineering #100DaysOfCode #PythonTips
To view or add a comment, sign in
-
-
yield is one of those Python keywords that looks simple until someone asks you to explain it. Most developers can tell you a function with yield in it produces values and works in for loops. Fewer can explain why that same function doesn't actually run when you call it. Turns out, that's the whole point. Generators (functions with yield) are functions that pause mid-execution and resume exactly where they left off: local variables, loop counters, everything intact. In my Python Context Managers series, I'm covering generators as a dedicated article because they are not a standalone concept. They are the engine behind @contextmanager, a cleaner way to build context managers in Python. You can't fully understand one without understanding the other. This article is a deep dive into generator functions: https://lnkd.in/dSNegaWK A function that remembers where it left off changes everything. #Python #SoftwareEngineering #Backend #Programming #WebDevelopment #BuildBreakLearn
To view or add a comment, sign in
-
You might want to take a look at this, Everybody says NumPy is faster than Python List. But, How fast ?? Well I looked into it !! So, here is the overhead of every value you use in Python. Let's say you use a value 42. Here is the detailed overhead. ob_refcnt - 8 bytes (For garbage collection, if reference count is zero, then python just deletes it from RAM) ob_type - 8 bytes (For storing what datatype that value belongs to, here that's integer) ob_digit - 8 bytes (For the actual value - 42). Therefore, 24 bytes for each value. Let's take it a step further. Say you have a 4 values to store just [1, 2, 3, 4] and Let's compare Python list vs NumPy array. Python List : Stores Pointers not the actual values and Hence, you need a list of pointers first, each pointer in the "pointer list" points to the actual value that is scattered across different locations of RAM. So, in-order to store 4 elements. 4 x 8 = 32 (pointer list) 4 x 24 = 96 (actual values) Therefore, 32 + 96 = 128 Bytes. NumPy arrays : It's contiguous and also homogeneous. Also, we don't have pointers model. Here we store actual values next to each other. Thus, giving us a easy traversal using strides. 4 x 8 = 32 Bytes. NumPy can store raw values directly because it enforces a single dtype. Since every element is the same size, it can locate any element using simple math (base + index × itemsize) instead of pointers. Python lists allow mixed types and that's exactly what forces the pointer model. Note: I am only comparing the storage models here. Both Python lists and NumPy arrays have their own object overhead which I've intentionally left out to keep the comparison clean. Apart from storage models. There is another reason why NumPy is so powerful in numerical computations and that is vectorization Vectorization in NumPy : When you do np.sum(a), NumPy runs optimized C code across the entire array in one shot no Python interpreter involved. A Python loop hits interpreter overhead on every single element. That's the real reason NumPy can be 10-100x faster for numerical operations. There is reason why this guy is named as "Numerical Python" !!
To view or add a comment, sign in
-
Day 16 / 30 - while Loops in Python What is a while Loop? A while loop keeps running its block of code as long as a condition is True. Unlike a for loop which runs a fixed number of times, a while loop runs an unknown number of times, it stops only when the condition becomes False. Perfect for situations where you don't know in advance how many repetitions you'll need. Syntax Breakdown while condition: # runs as long as condition is True # must update something to eventually make condition False while --> checks the condition before every single run condition --> any expression that evaluates to True or False How It Works, step by step Python checks the condition at the top of the loop If True --> it runs the indented block of code Goes back to the top and checks the condition again Keeps repeating until the condition becomes False When False --> exits the loop and continues the program for Loop vs while Loop for loop 1. Use when you know how many times to repeat 2. Looping over a list, range, sequence while loop 1. Use when you don't know how many times 2. Keep going until a condition changes The Infinite Loop -Most Common Mistake If your condition never becomes False, the loop runs forever, freezing your program. Always make sure something inside your loop changes the condition like incrementing a counter or taking user input so the loop can eventually stop. break and continue break - stops the loop immediately, exits even if the condition is still True continue → skips the current iteration and jumps back to the condition check Both break and continue work in for and while loops. Code Example # Count from 1 to 5 count = 1 while count <= 5: print("Count: " + str(count)) count = count + 1 # break — stop early number = 0 while number < 10: if number == 5: break # stops loop at 5 print(number) number += 1 Key Learnings ☑ A while loop runs as long as its condition is True , checks before every iteration ☑ Always update something inside the loop, counter, input, or flag or you'll get an infinite loop ☑ break exits the loop immediately when a condition is met ☑ continue skips the current iteration and jumps back to the condition check ☑ Use for when you know the count — use while when you don't Why It Matters While loops power real systems — PIN verification, login retry limits, game loops, servers waiting for requests. Anywhere your program needs to wait or keep trying until something changes, a while loop is the answer. My Takeaway A for loop is like a to-do list — you know how many items there are. A while loop is like waiting for a bus — you keep waiting until it arrives. Different tools, different situations. #30DaysOfPython #Python #LearnToCode #CodingJourney #WomenInTech
To view or add a comment, sign in
-
-
🚀 Python Series – Day 15: Exception Handling (Handle Errors Like a Pro!) Yesterday, we learned how to work with files in Python 📂 Today, let’s learn how to handle errors smartly without crashing your program ⚠️ 🧠 What is Exception Handling? Exception handling is a way to manage runtime errors so your program continues running smoothly. 👉 Without it → program crashes ❌ 👉 With it → program handles error gracefully ✅ 💻 Understanding try and except try: # risky code (may cause error) except: # runs if error occurs 🔍 How it Works: ✔️ Python first executes code inside try ✔️ If NO error → except is skipped ✔️ If error occurs → Python jumps to except ⚡ Example 1 (Basic) try: num = int(input("Enter number: ")) print(10 / num) except: print("Something went wrong!") 👉 If user enters 0 or text, error is handled. 🔥 Why Avoid Only except? Using only except is not a good practice ❌ 👉 It hides the real error. ✅ Best Practice: Handle Specific Errors try: num = int(input("Enter number: ")) print(10 / num) except ZeroDivisionError: print("Cannot divide by zero!") except ValueError: print("Please enter a valid number!") ⚡ Multiple Exceptions in One Line except (ZeroDivisionError, ValueError): print("Error occurred!") 🧩 else Block (Less Known 🔥) try: num = int(input("Enter number: ")) except ValueError: print("Invalid input") else: print("No error, result:", num) 👉 else runs only if no error occurs 🔒 finally Block (Very Important) try: print("Trying...") except: print("Error") finally: print("This always runs ✅") 👉 Used for cleanup (closing files, database, etc.) 🎯 Why This is Important? ✔️ Prevents crashes ✔️ Makes programs professional ✔️ Used in real-world apps, APIs, ML projects ⚠️ Pro Tips: 👉 Always use specific exceptions 👉 Use finally for cleanup 👉 Don’t hide errors blindly 📌 Tomorrow: Modules & Packages (Organize Your Code Like a Pro) Follow me to master Python step-by-step 🚀 #Python #Coding #Programming #DataScience #LearnPython #100DaysOfCode #Tech #MustaqeemSiddiqui
To view or add a comment, sign in
-
More from this author
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development