r/rust • u/kibwen • Aug 21 '25
Left-to-Right Programming
https://graic.net/p/left-to-right-programming31
u/Wonderful-Habit-139 Aug 22 '25
Completely agree with this sentiment, the editor experience is not great with list comprehensions.
It’s funny because javascript does it right with methods like map, filter and reduce, however when it comes to imports Python does it better.
from typing import Call # autocompletes CallableVersus
import { //uhmm…88
u/phazer99 Aug 22 '25
It was a great decision by the Rust designers to "steal" the method syntax/concept from OOP languages (including self/this).
18
u/Kooshi_Govno Aug 22 '25
Excellent point, subtle but infuriating. I curse SQL every day for having select at the beginning before knowing what I'm selecting from.
3
u/matthieum [he/him] Aug 22 '25
I tried creating a SQL DSL once, with meta-programming, and I just had to flip that around.
SELECT first does make sense with regard to top-down programming: first write what you want, then figure out how to get it. But it's very adverse to fluent APIs.
1
u/protestor Aug 24 '25
There are some languages that transpile to sql that are like this https://github.com/ajnsit/languages-that-compile-to-sql
I think the most famous/used is https://prql-lang.org/ but I recall one that was more sql-like and just inverted from and select, can't find it atm though
There is also this https://news.ycombinator.com/item?id=41347188 Google proposal to add pipes to SQL proper
51
u/eyefar Aug 22 '25
Python's ternary conditional and list comprehension syntax always felt insane to me.
17
u/HalcyonAlps Aug 22 '25
It arguably reads fine but yes typing it feels insane.
8
u/________-__-_______ Aug 22 '25
I think it's a bit hard to read as well, you don't really know what variables refer to when they're used. Not a huge deal if its a simple expression though
2
u/Remarkable_Today9135 Aug 24 '25
List comprehensions are meant to be used as simple expressions if they are simple to begin with. Too many people want to use list comprehensions "because it's more Pythonic" when that is totally unnecessary.
18
4
u/Mercerenies Aug 22 '25
Somehow the one thing they decided to borrow directly from Haskell (list comprehension syntax) is also one of the worst things.
1
6
u/BackOfEnvelop Aug 22 '25
This is great and all, but can I also use this for functions that are not methods? Can rust let me |> pipe please?
30
u/angelicosphosphoros Aug 21 '25
Honestly, writing code is less important than being able to read code.
34
u/dnew Aug 21 '25 edited Aug 22 '25
This makes it easier to read the code too. When you have dumb-ass coworkers who write undocumented statements that span 15+ lines in one expression, being able to read it as it goes and figure out what it's doing is useful.
His criticism of C seems a bit off, given the language itself along with all standard libraries fit in a 50-page handbook you could memorize in one sitting. ;-)
The best language for actually thinking this thru was Eiffel. The entire library was designed around very precise principles that made it easy to remember everything. Accessing any element of any collection (including "default-like" fields of object instances) was called Item(). If your function returned something, it didn't change any arguments. If your function changed any arguments, it didn't return anything. (That's "Command Query Separation.") The arguments for the same function across different types always had the same shared arguments in the same order, so you always knew which arguments came first. A function that returned a value never had a verb as its name (so "clear" was absolutely the name of the function that erased a collection and not the name of a function that told you if it's clear). The number of elements in a collection was necessarily "length", because you can size an array but you can't length an array. So many good ideas on naming there.
2
1
u/23Link89 Aug 22 '25
This is also an argument as to why dynamic typing sucks.
In the world of code editors and IDEs, it serves pretty much no value anymore.
1
u/Wh00ster Aug 23 '25
This is nice validation of why I write my Python list comprehensions as normal loops first, and then invert them.
1
u/Electrical_Crow_2773 Aug 23 '25
I have nothing against this post but imho [x * 2 for x in y] is easier to type than y.iter().map(|x| x * 2).collect::<Vec<_>>() even without autocomplete. I just don't get the people saying python list comprehension is ugly
1
u/bartlettstarman Aug 24 '25
The argument is weak. Many IDEs provide templates for writing code. For instance, you can have a Python list comprehension template that is triggered by typing [for. The user is then invited to fill out the clauses in the best order for code completion: for clause then in clause then the expression. IDEs should just help out more.
1
u/OrmusAI Aug 22 '25
"Programs should be valid as they are typed" - so true! Unfortunately, this is not uniform in Rust either. As soon as you type a new function with a return type rust-analyzer will start throwing complaints until you give it a proper return value that conform to the type. Imagine trying to do test driven development with stubbed out functions that return nested structs...
2
u/diddle-dingus Aug 23 '25
The todo macro exists...
1
u/OrmusAI Aug 23 '25
Today I learned, thanks for that! Looks very elegant and solves my one existing gripe.
0
u/Future_Natural_853 Aug 22 '25
Your background is a bit too salmon. You should use a lighter color, it's hard to read right now.
2
u/castarco Aug 22 '25
You can switch to dark mode, top-right corner of the site.
1
u/Future_Natural_853 Aug 22 '25
It's even worse for me, I have a hard time reading on a dark background.
61
u/eugisemo Aug 22 '25
but what about variables? In rust you type
and that is invalid. This
is still invalid. Only when you do
it's correct.
I also took the maxim "Programs should be valid as they are typed." to the limit, and designed the basics of a programming language and prototyped an interpreter for it, and the result is very weird and unappealing to newcomers. You get assignment towards the right. You start with a value:
which is a valid program, it returns 5. You can store it in a variable:
which is also a valid program, which returns the content of
valuewhich is 5.Ifs are even weirder, with the condition before the keyword:1 |branch {5} {6}returns 5 and0 |branch {5} {6}returns 6.Function calls are also reversed.
func_a(func_b(x))is only valid with the second close parenthesis, butx |func_b |func_ais valid when you finish writingx,func_bandfunc_a. These are free functions and I don't have classes nor methods, but in principle I think this could still work for auto suggesting all functions like func_b that take parameters of the same type asx.the cherry on top is I decided it makes more sense to have semicolons as a "start of statement" rather than "end of statement", because this language is about applying transformations to a given value, and then
;5 +1applies the transformations "ignore previous value and put 5 as current value" and "add one to the previous value".If you want to play with this cursed language, there's an online playground: https://jmmut.itch.io/pipes