Live data from Hacker News

Left to Right Programming

graic.net

301–310 of 372 posts

Re: Left to Right Programming

#301
post #39

SQL shows it's age by having exactly the same problem. Queries should start by the `FROM` clause, that way which entities are involved can be quickly resolved and a smart editor can aid you in writing a sensible query faster. The order should be FROM -> SELECT -> WHERE, since SELECT commonly gives names to columns, which WHERE will reference. You could even avoid crap like `SELECT * FROM table`, and just write `FROM…

It's written that way because it stems from relational algebra, in which the projection is typically (always?) written first. >The order should be FROM -> SELECT -> WHERE, since SELECT commonly gives names to columns, which WHERE will reference. Per the SQL standard, you can't use column aliases in WHERE clauses, because the selection (again, relational algebra) occurs before the projection. > You could even avoid cr…

> Per the SQL standard, you can't use column aliases in WHERE clauses, because the selection (again, relational algebra) occurs before the projection.

Except this works in most major vendor SQL implementations. And they all support relation aliases in SELECT... Seems the standards have long fell behind actual implementations.

Re: Left to Right Programming

#302
post #39

SQL shows it's age by having exactly the same problem. Queries should start by the `FROM` clause, that way which entities are involved can be quickly resolved and a smart editor can aid you in writing a sensible query faster. The order should be FROM -> SELECT -> WHERE, since SELECT commonly gives names to columns, which WHERE will reference. You could even avoid crap like `SELECT * FROM table`, and just write `FROM…

DuckDB accepts just that: https://duckdb.org/docs/stable/sql/query_syntax/from.html#fr...

Re: Left to Right Programming

#303
post #30

Earlier quoted context omitted.

> But it also makes the code harder to scan than Python. Quick readability at a glance seems like the bigger win than just better autocomplete. It depends a lot on what you’re accustomed to. You get used to whichever style. Just like different languages use different sentence order: subject, object and verb appear in all possible orders in different languages, and their speakers get along just fine. There are some si…

On the other hand, in Rust you often have to add something like .unwrap().unwrap().into:: >>() which kind of ruins the elegance :P

Often, such as this time. :)

The Rust and Python code are not equivalent: The Python code instantly produces the nested list. Rust map does not iterate over the list given to it, it only produces an iterator that you then have to drain. To make them equivalent, you need to add collect calls.

... which adds more typing, because then collect needs to know the types you want to collect into. To make the Rust code fully equivalent with the Python version, you need to do:

    let words_on_lines: Vec> = text.lines().map(|line| line.split_whitespace().collect()).collect();

    // alternatively, you can put the type arguments into the .collect() calls:
    let words_on_lines = text.lines().map(|line| line.split_whitespace().collect::>()).collect::>();
    // which approaches the level of noise you expect from rust,
    // but stylistically I much prefer having the type declaration near the definition.
But of course this example also highlights Rust's power. Often (usually) you don't need to do that, and you can instead use the iterator directly, saving all the intermediate allocations. With Rust, I can often write the kind of code I do in python, but without a single heap allocation. Also, it doesn't bind you to a single collection type that ships with the language; if you want to, you can easily use something like a vec with a short vec optimization instead.

But it definitely does inherit Perl's mantle as executable line noise.

Re: Left to Right Programming

#304
post #218

Earlier quoted context omitted.

It's written that way because it stems from relational algebra, in which the projection is typically (always?) written first. >The order should be FROM -> SELECT -> WHERE, since SELECT commonly gives names to columns, which WHERE will reference. Per the SQL standard, you can't use column aliases in WHERE clauses, because the selection (again, relational algebra) occurs before the projection. > You could even avoid cr…

Interestingly, the inventor of relational algebra for database management put the "FROM" first in his query language: https://dl.acm.org/doi/pdf/10.1145/1734714.1734718

What section did you see this? I see GET (i.e. SELECT) first.

Re: Left to Right Programming

#305
post #30

Earlier quoted context omitted.

On the other hand, in Rust you often have to add something like .unwrap().unwrap().into:: >>() which kind of ruins the elegance :P

Often, such as this time. :) The Rust and Python code are not equivalent: The Python code instantly produces the nested list. Rust map does not iterate over the list given to it, it only produces an iterator that you then have to drain. To make them equivalent, you need to add collect calls. ... which adds more typing, because then collect needs to know the types you want to collect into. To make the Rust code fully…

> alternatively, you can put the type arguments into the .collect() calls:

Instead of writing out a turbofish both times, I’d probably leave the first unannotated and put `::Vec>` on the second one.

Re: Left to Right Programming

#306
post #221

Earlier quoted context omitted.

This presupposes that the reader likes or even uses auto-complete. I do not, and there are many others like me.

And I'm sure there are people who program in Notepad or nano. If you want to develop software like it's the 80s again, go ahead, the rest of us appreciates at least basic IDE support.

Not liking auto-complete is a far cry from nano. I like syntax highlighting, I like on-the-fly type checking, I like linters, etc.

I use Neovim and tmux because I value snappy performance, and never having to leave the keyboard.

The reason I don’t like auto-complete is that it interrupts my thoughts. Once I’m typing code, I know what I want to do, and having things pop up is distracting. Before I’m typing, I’ll think about the problem, look at other code in the codebase, and/or read docs. None of that requires autocomplete, nor would it help me.

If you like autocomplete, great, use it, but don’t assume that it’s a binary choice between plaintext editing and Copilot.

Re: Left to Right Programming

#307
post #39

SQL shows it's age by having exactly the same problem. Queries should start by the `FROM` clause, that way which entities are involved can be quickly resolved and a smart editor can aid you in writing a sensible query faster. The order should be FROM -> SELECT -> WHERE, since SELECT commonly gives names to columns, which WHERE will reference. You could even avoid crap like `SELECT * FROM table`, and just write `FROM…

DuckDB accepts just that: https://duckdb.org/docs/stable/sql/query_syntax/from.html#fr...

Off topic, but I really wish DuckDB's FTS extension could add to the index as the table is added to. It's the only thing keeping me on sqlite for a project.

Re: Left to Right Programming

#308
post #282

I agree with the main ideas of this article. Context-first left-to-right seems like it would be easier for LLMs to write and autocomplete well too. This line, though, seems like it's using the wrong tools for the job: len(list(filter(lambda line: all([abs(x) >= 1 and abs(x) 0 for x in line]) or all([x To me it's crying out for the lines to be NumPy arrays: sum(1 for line in diffs if ((np.abs(line) >= 1) & (np.abs(lin…

Yeah, the `numpy` version still looks relatively cryptic (like, "line > 0" is still fine, but the numpy arrays broadcasting rules can quickly get out of hand) compared to the author's Javascript example, or any decent collections API in a typed "enterprise" language like C#/Java/Scala for that matter. Here's my personal favorite, a Kotlin version:

  diffs.countIf { line -> 
      line.all { abs(it) in 1..3 } and ( 
          line.all { it > 0} or
          line.all { it 

Re: Left to Right Programming

#309

Earlier quoted context omitted.

Often, such as this time. :) The Rust and Python code are not equivalent: The Python code instantly produces the nested list. Rust map does not iterate over the list given to it, it only produces an iterator that you then have to drain. To make them equivalent, you need to add collect calls. ... which adds more typing, because then collect needs to know the types you want to collect into. To make the Rust code fully…

> alternatively, you can put the type arguments into the .collect() calls: Instead of writing out a turbofish both times, I’d probably leave the first unannotated and put `::Vec >` on the second one.

Fair. I didn't even consider how that variant should be done, because whenever I find myself writing a turbofish I instantly ask myself, can I put this type in a definition somewhere instead?

Re: Left to Right Programming

#310
post #39

SQL shows it's age by having exactly the same problem. Queries should start by the `FROM` clause, that way which entities are involved can be quickly resolved and a smart editor can aid you in writing a sensible query faster. The order should be FROM -> SELECT -> WHERE, since SELECT commonly gives names to columns, which WHERE will reference. You could even avoid crap like `SELECT * FROM table`, and just write `FROM…

  > The order should be FROM -> SELECT -> WHERE, since SELECT commonly gives names to columns, which WHERE will reference.
Internally, most SQL engines actually process the clauses in the order FROM -> WHERE -> SELECT. This is why column aliases (defined in SELECT) work in the GROUP BY, HAVING and ORDER BY clauses, but not in the WHERE clause.
Post reply on HN