Hacker Newsnew | past | comments | ask | show | jobs | submit | more zkldi's commentslogin

cargo is a bad example as it's universally `cargo build`.

Make on its own is great but most of the time I've worked with C projects it's been cmake/autotools + global pkg installs, which you Do have to frequently look up.


> cargo is a bad example as it's universally `cargo build`.

Except if you want to use some specific feature. Or specific log level. Or build a specific crate in a workspace. Or...


How does make solve those proBlems?


Parent states that it's always "cargo build" which in 90% of the cases, is true.

Except for the projects that would require something like "cargo build --feature=wayland" for example, in order to run.

So "cargo build" ends up not being universal, and adding make will make it just "make build" regardless of what flags people use with cargo, meaning it's more universal than "cargo build".


There's quite a lot of mathematical mistakes (obvious ones, even) in DFWs work. I'm not sure whether it's intentional or not, but given that he also makes mistakes in his nonfiction it might just be that he's not a great mathematician.

Like in TPK, 0/0 is Infinity and in IJ, Pemulis explains differentiation completely incorrectly, also that stuff about the mean value theorem is irrelevant?!?

Still one of the greatest authors; deep technical correctness is more of a Pynchon thing.


Pemulis’ absolutely worthless and wrong but also completely self-assured descriptions of calculus are part of his character


That's funny, I just got to that part in my rereading of IJ and I had no idea it was completely wrong.


That makes sense to be honest, I thought it was intentional but then seeing so many other maths errors in other DFW works led me to believe it might very well not be.


Given that proofs must be finite (or it's easy to prove falsehoods), maybe the title is appropriate then.


I'll bite: What specific parts of rust syntax do people find so ugly?

I keep hearing this from decent chunks of people who don't write rust, but the language doesn't seem that far off C to me. It's certainly no haskell.


From what I've asked people, the complaints fall mainly into two categories:

* familiarity and aesthetics. Rust uses fewer round () parens, and more <> and {}. This makes it look alien, and people say it's unreadable when they don't immediately recognize the language constructs they know.

* misattributing difficulty of learning Rust concepts like lifetimes and generics to their syntax. People say they want less syntax, but they mean they don't want to explicitly specify things like ownership and trait bounds.


The more interesting follow up question is: "How would you express the same semantics with a different syntax?" Too often discussions about Rust's ugly syntax lack this crucial component.


> How would you express the same semantics with a different syntax?

This isn't the problem, the problem is "... and keep the syntax C++-like?".


Is it? I don't know if keeping Rust's syntax C++-like is a stated goal of the project, but okay sure we can add that caveat to my question.

The big problem I see is that people will say "Lifetime annotations are ugly and noisy" and when pressed on the issue will eventually concede that they just want GC(which is not about syntax, but semantics)


It was a goal, though lower priority than other goals. You can see this in the way Rust is largely “curly braces and semicolons” but at times when there’s good reasons it diverged from that, like the ML style let syntax.


> I don't know if keeping Rust's syntax C++-like is a stated goal of the project

They won't change the syntax, the whole discussion is hypothetically anyway. What I wanted to express is that most people want a C++-style syntax (of generics), even if they complain about Rust's syntax.


I say this as a Rust enjoyer, but I think what most people mean when they say this is that there's a lot going on, especially in the function definition syntax. When you start adding in lifetimes and generics with bounds, async, &muts, where clauses... it really does become unreadable. I don't really see a way to fix this without making the syntax even more verbose, or aggressively simplifying the type system to the point that function argument inference becomes viable, but then you might end up in a situation like Swift's where type checking a simple expression takes an excessively long time.

That and the colon-colons (::), probably. Those can add a lot of noise.


I suspect the colon-colons were a mistake. Java uses periods for both modules and classes, and it doesn't seem to be a problem there.

Lifetimes are really ugly. You usually don't need to write them explicitly, but that's not a real excuse.


> colon-colons

I prefer "quad-dot". Rolls off the tongue better. :)


https://web.archive.org/web/20230713231438/http://bash.org/?...

  < Andys> oh dear
  < Andys> in ruby, symbols are represented with a prepended colon
  < Andys> eg.   :flag
  < Andys> so some guy tshirt that said ":sex"
  < Andys> which everyone at railscamp knew meant "Sex symbol"
  < Andys> he wore it until someone pointed out that to non-rubyists it said "Colon sex"



I think it's not that much the specific parts as it is the combination of (sometimes obscure) symbols forming dense blocks of sigils that you have to carefully pick apart to understand what the code is doing. It's easier to reason about code if it uses words instead of symbols, and Rust seems to desperately want to avoid using actual words (I don't count "fn" as a word, and "pub" is a word, but for me it's somewhere where you go to have a drink after work). Ok, I know there is a long tradition of doing this in C-family languages, but Rust has driven it to new heights, and it has a lot more concepts (with their attached symbols) that you have to keep in your head.


I hate the unpronounceable sigils of languages like Haskell, but C-style abbreviations don't really bother me somehow. The abbreviations help you remember what the words are, at least, and for me this seems to be enough.


>I keep hearing this from decent chunks of people who don't write rust

That's exactly the people you want to hear from if you're trying to improve adoption.


Here's my litmus test: read the source aloud. Over the phone to a person who doesn't see your screen, if needed. Did you have an obvious, understandable, and simple pronunciation for everything, that wasn't just reading ASCII characters one by one?

Now pretend the other person is a smart and experienced programmer, but has never heard of Rust. How would they write down what you just told them, without any idea of Rust's syntax? That's the non-ugly version of Rust.


    function max with type parameter T
    with arguments
    a of type T and b of type T
    and returns a value of type T
    where T implements trait PartialEq
Vs

    fn max<T>(a: T, b: T) -> T where T: PartialEq


Limiting examples to a subset of Rust syntax will produce more readable answers, sure. You have no lifetimes and no borrows, and very limited generics.


The information density of the "human syntax" Rust syntax both remain linear in size, but with a significant different N.

    function max
    with
        a lifetime a,
        a lifetime b,
        and type parameter T
    with
        argument a of a reference to type T that lives as long as lifetime a
        argument b of a reference to type T that lives as long as lifetime b
    and returns a value of type parameter T
    where T implements trait PartialEq
Vs

    fn max<'a, 'b, T: PartialEq>(a: &'a T, b: &'b T) -> T

If you want a real life example:

    #[stable(feature = "rust1", since = "1.0.0")]
    impl<'a, T, A: Allocator> IntoIterator for &'a Vec<T, A> {
        type Item = &'a T;
        type IntoIter = slice::Iter<'a, T>;

        fn into_iter(self) -> Self::IntoIter {
            self.iter()
        }
    }


    An implementation of trait IntoIterator
    (that has been stable since Rust 1.0.0)
    with a lifetime a
        a type parameter T
        a type parameter A which implements the trait Allocator
    for a borrow for the duration of lifetime a of type Vec with type parameters T and A
    
        it has an associated type Item, which is a borrow for the duration of lifetime a of type T
        it has an associated type IntoIter, which is type Iter from module slice with parameters lifetime a and type T

        it has a method into_iter
            that consumes the receiver
            and returns associated type IntoIter
            
            the methods body
            calls method iter on the receiver
            and returns its resulting value


I'm not arguing that complex things will somehow become non-complex.

However, none of the human syntax of Rust includes things like :: or '. To a first approximation[1], those are the parts that people can experience as "ugly", and they are not present in the human syntax. This is what people mean when they say "sigil heavy" or "punctuation based" syntax -- things that are generally are not read out as such. This is the space where you can make arguments about beauty.

[1]: Only roughly so because your chosen human syntax still encodes some Rust syntax decisions like predeclaring generic lifetimes and types, and using "where" instead of an inline clause. Those parts of syntax can also be shuffled around for subjective values of "not ugly".


Lifetime bounds on a trait object argument can be confusing.

I have to look up how to write the where part properly every single time.


Fishtail, lifetime and closure syntaxes are rather ugly. Just specifically when combined in practice, not alone in isolated examples.


For what is worth, the turbo fish falls from the decision to use <> for generics (for familiarity for C++ and Java developers) and a desire to make the syntax non-ambiguous (side stepping the C++ problem of having to delay determining if something is a type path or a comparison, mixing parsing and name resolution).


> What specific parts of rust syntax do people find so ugly? ... the language doesn't seem that far off C to me. It's certainly no haskell.

Make that "not far off C++" (C is really beautiful in comparison), and there's your answer.


[...] You've heard of the Kirghiz Light? well that's the ass end of a firefly compared to what we're gonna—oh, you haven't heard of the—oh, well, too bad. [...]


It's about six days ride if you're hauling ass


Could you give any examples of syntax you've hit that didn't make sense or seemed awful?


Sure, "let foo = bar" is one of the worst things any language can do.

Let is redundant, that's what the = is for. Unless it's meant to be equivalent to 'var' or 'auto', in which case it's even worse.

Let contains no information, it's pointless clutter that replaced something that did contain vital information. Let tells you the next symbol is a variable. What type? Who knows and who cares, it's a variable, deal with it. C marks a symbol as a variable by using its type name.

I mean, this was a very large part of why Perl is so miserable. I will never understand why people choose to implement this in modern languages.

Anyway, variables and parameters without explicit, visible type information is a hard no for me. I took a sniff of a couple rust projects, saw this mess, and decided that rust is not for me. I don't care about all the other magical benefits that cure all my ails, this feature is a dealbreaker, full stop.


`let` defines a new binding, as opposed to changing the value of an existing binding. You can't remove `let` to keep only `=` because it has a different use case.

Not indicating the type is idiomatic in Rust, but you can annotate it:

    let commit_message: String = repo.head().peel_to_commit().ok()?.message()?.into();
Here this is useful to specify the type `into` should convert to. However, if rewritten as:

    let commit_message = repo.head().peel_to_commit().ok()?.message()?.to_string();
Then it is useless because we're already specifying the type of the variable by using `to_string`.

Note that IDEs are displaying type hints anyway (without you having to type them), so you don't have to suffer if walking through a codebase where people are annotating their types too little for comfort


an errant comma after the last object property doesn't cause any issues


Tools win not because they are "better" in some platonic ideal of a programming language but because they are more practical for solving the problems people have.

Python, JS, C, Bash aren't even particularly great at the problems they solve, but they succeed mostly on inertia (it's where all the libraries are, it's what people know) and occupying developer mindshare.

They are full of obvious design mistakes; things that not even the creators of the language (nor any of its users) can defend, yet those languages are used infinitely more than languages that eschew those mistakes. Why? Because they solve problems people have.

If this sounds terrible to you, the good news is that there is a tonne of low-hanging fruit in the programming language design space. Consider that most developers know nothing of sum-types, or eschew the idea of typing entirely. Consider that most developers see no fundamental problem behind having to venv or dockerise software lest it bitrot over a month. Consider that programmers actually use bash.

These terrible, obviously broken tools are somehow the most pragmatic things we actually have. The fruit is low-hanging; the door is wide open, if you wish to grab it.


> The fruit is low-hanging

This is basically the only part of your post I disagree with, for reasons you pointed out yourself.

Low-hanging-fruit would imply that it is easy to displace these flawed languages with something better. And you have made a beautiful argument for why that is very very very difficult indeed.


> Python, JS, C, Bash aren't even particularly great at the problems they solve

I would argue the "problem" that Python really solves is the amount of engineering effort required to read and write code for common software use cases. Ie, it's purpose is to help developers write better code faster and easier than other languages, while execution speed has usually had a lower priority. In that framing, it's great at solving the problem of development time and old code being hard to maintain, and that's why so many engineers like myself love it.


Weird. I've seen this exact job posted by this exact company every single month for the past year.

I even applied at one point and heard nothing back. Looks like nobody else has ever heard anything back either.

Bizarre.


I was thinking about applying but after some research it seemed a bit shady. Former cofounder stole 3.6 billion in BTC https://news.ycombinator.com/item?id=30261118


I assure you that he has had nothing to do with the company in a long time, since before any of those newsworthy events took place. I'm the only person at the company that's ever spoken with him, and if you got to know me you'd understand that I'm at 0 risk of being involved in anything shady like that. I don't blame you for bringing it up, that news is still so shocking to me that I can't believe it's real.


Thank you for applying. I've asked someone to double check into your application.

We started receiving 20x more applicants than usual about this time last year when other tech companies were increasingly doing hiring freezes and layoffs. We're hiring consistently every month (including 5 new hires in the last month), especially from applicants from hacker news. Unfortunately we're not able to hire all the talented people that reach out. We have budget to grow faster, but internally, we have to be careful to not hire too quickly so that it's not chaotic for new people on the team with too little support from long-standing team members. We're trying our best to manage the higher volume of applicants, but clearly we let you down on communication so please accept my apology.


Yep, that Junior role had about 700 applicants last I checked on LinkedIn. No way theres nobody qualified in that pool.


You're right, there's many qualified applicants in that pool! These aren't singular positions, but evergreen positions we're consistently hiring for every month.

The reason I don't vary the job descriptions is because I would rather start with an excellent candidate and customize the position to match them than to start with an excellent job description and look for someone to match it. The person is the important part, not the job description.

The reason for the junior position is because some of the most talented people are overly humble and don't think they are qualified to apply, but are more willing when they see a junior position is available.


They do it to pretend that they are growing as a company. I think we should call out bad jobs, maybe through a Twitter account or something that can hold companies accountable.


We are a growing company. We've grown headcount about 50% year over year the last several years.


What's rule 0?


Show examples on the main web page.

Try and find an AngelScript example. It's stupidly hard. Compare it to these web sites:

https://dlang.org/

https://koka-lang.github.io/koka/doc/index.html

https://vale.dev/

http://mu-script.org/

https://go.dev/

https://www.hylo-lang.org/

Sadly Rust fails this too but at least the Playground is only one click away. And Rust is mainstream anyway so it doesn't matter as much. I completely failed to find a single AngelScript example accessible from my phone's browser. Even its Wikipedia page doesn't have any.


why isn't the default secure? if the default isn't secure we have learned time and time again that people will use the default unknowingly exposing themselves to security holes.

Here's just a couple examples off the top of my head:

- `$variables` in bash are subject to arbitrary code execution via word splitting without escaping

- PHP register_globals

- PHP, express, and some others parse `?a[b]="foo"` in a query string as an object, allowing for prototype pollution or other exploits

- string concatenation for SQL + escape_string being the default for years

- perl array expansion in function calls

- XML entity inclusion on by default allowing you to read arbitrary files

- log4j executing arbitrary code inside its logs

- passing a variable to printf's first arg

- no difference between escaped and unescaped tags in php

- xargs splitting on whitespace

- yaml allowing arbitrary code execution (it got rails good!)

and there's probably loads more.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: