Skip to content

Left to Right Programming

Technology
27 11 0
  • This post did not contain any content.
  • This post did not contain any content.

    IMO all those examples are less readable than writing it in an imperative way using good function and variable names.

    Also, len() is a Python convention and a built-in function that calls __len__() on that object. It's even more established than .length in JS, so I really don't see why someone would expect anything else. And even then, one could call my_list.__len__() if they really wanted to be sure and have that "left to right" bonus.

  • This post did not contain any content.

    That sounds a lot like Functional Programming

  • This post did not contain any content.

    I also tend to prefer left to right and use threading macros a lot.

  • Except they don't like functional primitives like map unless they're namespaced to iterable types...

  • This post did not contain any content.

    I'm always suspicious of people who say that a language is suboptimal and use as evidence some filthy one-liner. Maybe if you bothered to write some whitespace and didn't write the language ignorant of its features (like generator expressions) you would end up with better code?

    sum(
        all(
            abs(x) >= 1 and abs(x) <= 3 for x in line
        ) and (
            all(x > 0 for x in line) or
            all(x < 0 for x in line)
        )
        for line in diffs
    )
    

    You no longer have to "jump back and forth" except one single time - you have to look to the end to see where line is coming from and then you can read the body of the main expression from start to finish.

    People don't, in fact, read code from top to bottom, left to right; they read it by first looking at its "skeleton" - functions, control flow, etc - until finding the bit they think is most important to read in detail. That implies that "jumping back and forth" is a natural and necessary part of reading (and hence writing) code, and so is nothing to fear.

    There is still a slight advantage to not having to jump around, but consider the costs: in Javascript, map and filter are methods on Array and some other types. So how are you going to implement them for your custom iterable type? Do you have to do it yourself, or write lots of boilerplate? It's easy in Python. It's not bad in Rust either because of traits, but what this all means is that to get this, you need other, heavy, language features.

    In practice, you often know what a comprehension is iterating over due to context. In those situations, having what the comprehension produces be the most prominent is actually a boon. In these scenarios in Rust/JS you are left skipping over the unimportant stuff to get to what you actually want to read.

  • I'm always suspicious of people who say that a language is suboptimal and use as evidence some filthy one-liner. Maybe if you bothered to write some whitespace and didn't write the language ignorant of its features (like generator expressions) you would end up with better code?

    sum(
        all(
            abs(x) >= 1 and abs(x) <= 3 for x in line
        ) and (
            all(x > 0 for x in line) or
            all(x < 0 for x in line)
        )
        for line in diffs
    )
    

    You no longer have to "jump back and forth" except one single time - you have to look to the end to see where line is coming from and then you can read the body of the main expression from start to finish.

    People don't, in fact, read code from top to bottom, left to right; they read it by first looking at its "skeleton" - functions, control flow, etc - until finding the bit they think is most important to read in detail. That implies that "jumping back and forth" is a natural and necessary part of reading (and hence writing) code, and so is nothing to fear.

    There is still a slight advantage to not having to jump around, but consider the costs: in Javascript, map and filter are methods on Array and some other types. So how are you going to implement them for your custom iterable type? Do you have to do it yourself, or write lots of boilerplate? It's easy in Python. It's not bad in Rust either because of traits, but what this all means is that to get this, you need other, heavy, language features.

    In practice, you often know what a comprehension is iterating over due to context. In those situations, having what the comprehension produces be the most prominent is actually a boon. In these scenarios in Rust/JS you are left skipping over the unimportant stuff to get to what you actually want to read.

    I agree with you that the one liner isn't a good example, but I do prefer the "left to right" syntax shown in the article. My brain just really likes getting the information in this order: "Iterate over Collection, and for each object do Operation(object)".

    The cost of writing member functions for each class is a valid concern. I'm really interested in the concept of uniform function call syntax for this reason, though I haven't played around with a language that has it to get a feeling of what its downsides might be.

  • I agree with you that the one liner isn't a good example, but I do prefer the "left to right" syntax shown in the article. My brain just really likes getting the information in this order: "Iterate over Collection, and for each object do Operation(object)".

    The cost of writing member functions for each class is a valid concern. I'm really interested in the concept of uniform function call syntax for this reason, though I haven't played around with a language that has it to get a feeling of what its downsides might be.

    I was also thinking about UFCS. I do like it for its flexibility, but I did try it in Nim one time and was left feeling unsure. Unfortunately I now can't remember what exactly I didn't like about it.

  • This post did not contain any content.

    Is string length len, length, size, count, num, or # ? Is there even a global function for length? You won’t know until you try all of them.

    This is Python basics, so the argument would be to optimize readability specifically for people who have zero familiarity with the language.

    (The other examples have the same general direction of readability tradeoff to the benefit of beginners, this one was just simplest to pick here)

    That's a valid tradeoff to discuss, if discussed as a tradeoff. Here it is not. The cost to readability for anyone with language familiarity appear to be not even understood.

  • Is string length len, length, size, count, num, or # ? Is there even a global function for length? You won’t know until you try all of them.

    This is Python basics, so the argument would be to optimize readability specifically for people who have zero familiarity with the language.

    (The other examples have the same general direction of readability tradeoff to the benefit of beginners, this one was just simplest to pick here)

    That's a valid tradeoff to discuss, if discussed as a tradeoff. Here it is not. The cost to readability for anyone with language familiarity appear to be not even understood.

    The point of the article is about how IDE's can't validate certain things as you type them in this order. The example of a string length function could be replaced by any other API.

  • The point of the article is about how IDE's can't validate certain things as you type them in this order. The example of a string length function could be replaced by any other API.

    That is one of the points, yes.

    But, the reason for wanting the IDE to validate based on partially entered expressions is given as making it easier to follow the code for a person working left-to-right.

    And it's not an invalid thing to want, but I expect the discussion to also include how it affects reading the code for a non-beginner.

  • I'm always suspicious of people who say that a language is suboptimal and use as evidence some filthy one-liner. Maybe if you bothered to write some whitespace and didn't write the language ignorant of its features (like generator expressions) you would end up with better code?

    sum(
        all(
            abs(x) >= 1 and abs(x) <= 3 for x in line
        ) and (
            all(x > 0 for x in line) or
            all(x < 0 for x in line)
        )
        for line in diffs
    )
    

    You no longer have to "jump back and forth" except one single time - you have to look to the end to see where line is coming from and then you can read the body of the main expression from start to finish.

    People don't, in fact, read code from top to bottom, left to right; they read it by first looking at its "skeleton" - functions, control flow, etc - until finding the bit they think is most important to read in detail. That implies that "jumping back and forth" is a natural and necessary part of reading (and hence writing) code, and so is nothing to fear.

    There is still a slight advantage to not having to jump around, but consider the costs: in Javascript, map and filter are methods on Array and some other types. So how are you going to implement them for your custom iterable type? Do you have to do it yourself, or write lots of boilerplate? It's easy in Python. It's not bad in Rust either because of traits, but what this all means is that to get this, you need other, heavy, language features.

    In practice, you often know what a comprehension is iterating over due to context. In those situations, having what the comprehension produces be the most prominent is actually a boon. In these scenarios in Rust/JS you are left skipping over the unimportant stuff to get to what you actually want to read.

    People don’t, in fact, read code from top to bottom, left to right

    100% this.

    This false premise is also why a few (objectively wrong) people defend writing long essays: functions with hundreds of lines and files with thousands; saying "then you don't have to go back and forth to read it", when in fact, no one should be reading it like a novel in the first place.

    Once you get used with list and dict comprehensions, they read just fine. Much like the functional approach is not really that readable for a newcomer either.

  • The point of the article is about how IDE's can't validate certain things as you type them in this order. The example of a string length function could be replaced by any other API.

    The example of a string length function could be replaced by any other API

    I don't know about that, len is a built-in -- like str, abs, bool. There are only a few of them and they're well known by people familiar to the language (which seems to exclude the article author). Their use is more about the language itself than about what to expect from a particular API.

    In fact, most Python APIs that go beyond built-in usage actually look much more object-oriented with "left-to-right" object.method() calls. So this argument seems silly and goes away with some familiarity with that language.

  • Comprehension is functional programming too, they arise from list monad https://www.schoolofhaskell.com/school/starting-with-haskell/basics-of-haskell/13-the-list-monad
    And Haskell do notation indeed reads top-down, unlike Python, but I find both quite readable.

  • That is one of the points, yes.

    But, the reason for wanting the IDE to validate based on partially entered expressions is given as making it easier to follow the code for a person working left-to-right.

    And it's not an invalid thing to want, but I expect the discussion to also include how it affects reading the code for a non-beginner.

    It's got nothing to do with being a beginner. I've been working as a professional software developer for ~15 years now and still I have to use new libraries/frameworks/in-house dependencies quite frequently. I know how to get the length of a string, and so does the author of the article.

    But that's why it's a simple example and nothing more, and it applies to everything else. We write left to right, and IDEs autocomplete left to right, so it makes sense for languages to be designed to work that way.

    There's a lot of reasons why Java works much better with IDEs than python, and this is one of them.


    Besides that, it is best practice to show problems on simple, easy to follow use cases that highlight exactly the problem in question without further fluff. It's expected that a non-beginner can abstract that problem into more difficult use cases, so I don't think OOP did anything wrong with choosing string length as an example.

  • The example of a string length function could be replaced by any other API

    I don't know about that, len is a built-in -- like str, abs, bool. There are only a few of them and they're well known by people familiar to the language (which seems to exclude the article author). Their use is more about the language itself than about what to expect from a particular API.

    In fact, most Python APIs that go beyond built-in usage actually look much more object-oriented with "left-to-right" object.method() calls. So this argument seems silly and goes away with some familiarity with that language.

    The argument is not silly, it totally makes sense, and your point even proves that.

    A lot of libraries use module-level globals and if you use from imports (especially from X import *) you get exactly that issue.

    Yes, many more modern APIs use an object-oriented approach, which is left-to-right, and that's exactly what OOP is argueing for. If you notice, he didn't end the post with "Make good languages" but with "Make good APIs". He highlights a common problem using well-known examples and generalizes it to all APIs.

    The auther knows full well that this blog post will not cause Python to drop the List comprehension syntax or built-in functions. What he's trying to do is to get people to not use non-LTR approaces when designing APIs. All the points he made are correct, and many are even more pressing in other languages.

    For example, for a hobby project of mine I have to use C/C++ (microcontrollers). And this problem is huge in C libraries. Every function is just dumped into the global name space and there's no way to easily find the right function. Often I have to go to google and search for an external documentation or open up the header files of a project to find a function that does what I want, instead of being able to just follow the IDE autocomplete on an object.

    And sure, if I know every library and framework I use inside out and memorized all functions, methods, objects, variables and fields, then it's easy, but unless you work 30 years in a bank where you maintain the same old cobol script for decades, that's not going to happen.

  • I'm always suspicious of people who say that a language is suboptimal and use as evidence some filthy one-liner. Maybe if you bothered to write some whitespace and didn't write the language ignorant of its features (like generator expressions) you would end up with better code?

    sum(
        all(
            abs(x) >= 1 and abs(x) <= 3 for x in line
        ) and (
            all(x > 0 for x in line) or
            all(x < 0 for x in line)
        )
        for line in diffs
    )
    

    You no longer have to "jump back and forth" except one single time - you have to look to the end to see where line is coming from and then you can read the body of the main expression from start to finish.

    People don't, in fact, read code from top to bottom, left to right; they read it by first looking at its "skeleton" - functions, control flow, etc - until finding the bit they think is most important to read in detail. That implies that "jumping back and forth" is a natural and necessary part of reading (and hence writing) code, and so is nothing to fear.

    There is still a slight advantage to not having to jump around, but consider the costs: in Javascript, map and filter are methods on Array and some other types. So how are you going to implement them for your custom iterable type? Do you have to do it yourself, or write lots of boilerplate? It's easy in Python. It's not bad in Rust either because of traits, but what this all means is that to get this, you need other, heavy, language features.

    In practice, you often know what a comprehension is iterating over due to context. In those situations, having what the comprehension produces be the most prominent is actually a boon. In these scenarios in Rust/JS you are left skipping over the unimportant stuff to get to what you actually want to read.

    Did we read the same blog post?

    Not a single time did OOP talk about readability. That was not a point at all, so I don't know why you are all about readability.

    It was all about having a language that the IDE can help you write in because it knows what you are talking about from the beginning of the line.

    The issue with the horrible one-liner (and with your nicely split-up version) is that the IDE has no idea what object you are talking about until the second-to-last non-whitespace character. The only thing it can autocomplete is "diffs". Up until you typed the word, it has no idea whether sum(), all(), abs(), <, >, or for-in actually exist for the data type you are using.

    If you did the same in Java, you'd start with diffs and from then on the IDE knows what you are talking about, can help you with suggesting functions/methods, can highlight typos and so on.

    That was the whole point of the blog post.

  • People don’t, in fact, read code from top to bottom, left to right

    100% this.

    This false premise is also why a few (objectively wrong) people defend writing long essays: functions with hundreds of lines and files with thousands; saying "then you don't have to go back and forth to read it", when in fact, no one should be reading it like a novel in the first place.

    Once you get used with list and dict comprehensions, they read just fine. Much like the functional approach is not really that readable for a newcomer either.

    The blog post wasn't about reading, but about writing. And people usually do write top-to-bottom, left-to-right.

    The whole point of the blog post was to write code that the IDE can help you with when writing. It didn't go into readability even once.

  • This post did not contain any content.

    I'll agree that list comprehensions can be a bit annoying to write because your IDE can't help you until the basic loop is done, but you solve that by just doing [thing for thing in things] and then add whatever conditions and attr access/function calls you need.

  • Did we read the same blog post?

    Not a single time did OOP talk about readability. That was not a point at all, so I don't know why you are all about readability.

    It was all about having a language that the IDE can help you write in because it knows what you are talking about from the beginning of the line.

    The issue with the horrible one-liner (and with your nicely split-up version) is that the IDE has no idea what object you are talking about until the second-to-last non-whitespace character. The only thing it can autocomplete is "diffs". Up until you typed the word, it has no idea whether sum(), all(), abs(), <, >, or for-in actually exist for the data type you are using.

    If you did the same in Java, you'd start with diffs and from then on the IDE knows what you are talking about, can help you with suggesting functions/methods, can highlight typos and so on.

    That was the whole point of the blog post.

    I dunno, did we?

    Screenshot from the post

    I think rust's iterator chains are nice, and IDE auto-complete is part of that niceness. But comprehension expressions read very naturally to me, more so than iterator chains.

    I mean, how many python programmers don't even type hint their code, and so won't get (accurate) auto-complete anyway? Auto-completion is nice but just not the be-all and end-all.

  • 543 Stimmen
    95 Beiträge
    0 Aufrufe
    S
    The instance matters: some will ban you if you cite too many credible articles which bring up uncomfortable truths. No matter what one's stance is on a political subject, there will be some uncomfortable truths. Unlike a Hollywood hero movie.
  • Security vulnerability for Nvidia drivers on Linux/Windows

    Technology technology
    3
    58 Stimmen
    3 Beiträge
    27 Aufrufe
    mimicjar@lemmy.worldM
    ::: spoiler do not click gottem :::
  • Ready-made stem cell therapies for pets could be coming

    Technology technology
    1
    1
    27 Stimmen
    1 Beiträge
    23 Aufrufe
    Niemand hat geantwortet
  • 302 Stimmen
    12 Beiträge
    148 Aufrufe
    J
    Really?!
  • 677 Stimmen
    179 Beiträge
    4k Aufrufe
    D
    Thats what the firewall rules do too, don't allow internet connection if there's no vpn connection. Firewall is a system-wide solution that always works, while qbt config relies heavily on the application implementing interface binding properly. Which it doesn't fully btw.
  • Canada Drops Digital Tax That Infuriated Trump to Restart Trade Talks

    Technology technology
    17
    80 Stimmen
    17 Beiträge
    169 Aufrufe
    R
    Jesus fuck that’s a lot of days
  • 454 Stimmen
    149 Beiträge
    3k Aufrufe
    eyekaytee@aussie.zoneE
    They will say something like solar went from 600gw to 1000 thats a 66% increase this year and coal only increased 40% except coal is 3600gw to 6400. Hrmmmm, maybe these numbers are outdated? Based on this coal and gas are down: In Q1 2025, solar generation rose 48% compared to the same period in 2024. Solar power reached 254 TWh, making up 10% of total electricity. This was the largest increase among all clean energy sources. Coal-fired electricity dropped by 4%, falling to 1,421 TWh. Gas-fired power also went down by 4%, reaching 67 TWh https://carboncredits.com/china-sets-clean-energy-record-in-early-2025-with-951-tw/ are no where close to what is required to meet their climate goals Which ones in particular are you talking about? Trump signs executive order directing US withdrawal from the Paris climate agreement — again https://apnews.com/article/trump-paris-agreement-climate-change-788907bb89fe307a964be757313cdfb0 China vowed on Tuesday to continue participating in two cornerstone multinational arrangements -- the World Health Organization and Paris climate accord -- after newly sworn-in US President Donald Trump ordered withdrawals from them. https://www.france24.com/en/live-news/20250121-china-says-committed-to-who-paris-climate-deal-after-us-pulls-out What's that saying? You hate it when the person you hate is doing good? I can't remember what it is I can't fault them for what they're doing at the moment, even if they are run by an evil dictatorship and do pollute the most I’m not sure how european defense spending is relevant It suggests there is money available in the bank to fund solar/wind/battery, but instead they are preparing for? something? what? who knows. France can make a fighter jet at home but not solar panels apparently. Prehaps they would be made in a country with environmental and labour laws if governments legislated properly to prevent companies outsourcing manufacturing. However this doesnt absolve china. China isnt being forced at Gunpoint to produce these goods with low labour regulation and low environmental regulation. You're right, it doesn't absolve china, and I avoid purchasing things from them wherever possible, my solar panels and EV were made in South Korea, my home battery was made in Germany, there are only a few things in my house made in China, most of them I got second hand but unfortunately there is no escaping the giant of manufacturing. With that said it's one thing for me to sit here and tut tut at China, but I realise I am not most people, the most clearest example is the extreme anti-ai, anti-billionaire bias on this platform, in real life most people don't give a fuck, they love Amazon/Microsoft/Google/Apple etc, they can't go a day without them. So I consider myself a realist, if you want people to buy your stuff then you will need to make the conditions possible for them to WANT to buy your stuff, not out of some moral lecture and Europe isn't doing that, if we look at energy prices: Can someone actually point out to me where this comes from? ... At the end of the day energy is a small % of EU household spending I was looking at corporate/business energy use: Major European companies are already moving to cut costs and retain their competitive edge. For example, Thyssenkrupp, Germany’s largest steelmaker, said on Monday it would slash 11,000 jobs in its steel division by 2030, in a major corporate reshuffle. https://oilprice.com/Latest-Energy-News/World-News/High-Energy-Costs-Continue-to-Plague-European-Industry.html Prices have since fallen but are still high compared to other countries. A poll by Germany's DIHK Chambers of Industry and Commerce of around 3,300 companies showed that 37% were considering cutting production or moving abroad, up from 31% last year and 16% in 2022. For energy-intensive industrial firms some 45% of companies were mulling slashing output or relocation, the survey showed. "The trust of the German economy in energy policy is severely damaged," Achim Dercks, DIHK deputy chief executive said, adding that the government had not succeeded in providing companies with a perspective for reliable and affordable energy supply. https://www.reuters.com/business/energy/more-german-companies-mull-relocation-due-high-energy-prices-survey-2024-08-01/ I've seen nothing to suggest energy prices in the EU are SO cheap that it's worth moving manufacturing TO Europe, and this is what annoys me the most. I've pointed this out before but they have an excellent report on the issues: https://commission.europa.eu/document/download/97e481fd-2dc3-412d-be4c-f152a8232961_en?filename=The+future+of+European+competitiveness+_+A+competitiveness+strategy+for+Europe.pdf Then they put out this Competitive Compass: https://commission.europa.eu/topics/eu-competitiveness/competitiveness-compass_en But tbh every week in the EU it seems like they are chasing after some other goal. This would be great, it would have been greater 10 years ago. Agreed
  • 493 Stimmen
    154 Beiträge
    4k Aufrufe
    Q
    Lets see.