Hacker News new | past | comments | ask | show | jobs | submit login

Nah that part I'm not worried about. The "cheating" is omitting the rest of the line. What you really needed was:

  var y = Enumerable.Range(1, 50).Where((x, i) => i % 4 == 0).Where(e => e % 3 == 0).Skip(1).Select(e => e + 4).ToArray();
Compare that against:

  y = [t[1] for t in enumerate(range(1, 50, 4)) if t[0] % 3 == 0][2:]
It's almost twice as long, and doesn't exactly make up for it with readability either.



What you're missing is that C# example works on any Enumerable. And it's very hard to explain how damn important and impressive this is without trying it first.

Yes, it's more verbose, but I can swap that initial array for a List, or a collection, or even an external async datasource, and my code will not change. It will be the same Select.Where....


> What you're missing

I'm not missing it.

> is that C# example works on any Enumerable. And it's very hard to explain how damn important and impressive this is without trying it first.

Believe me I've tried (by which I mean used it a ton). I'm not a newbie to this. C# is great. Nobody was saying it's unimportant or unimpressive or whatever.

> Yes, it's more verbose, but I can swap that initial array for a List, or a collection, or even an external async datasource, and my code will not change

Excellent. And when you want that flexibility, the verbosity pays off. When you don't, it doesn't. Simple as that.


> Excellent. And when you want that flexibility, the verbosity pays off. When you don't, it doesn't. Simple as that.

It's rarely as simple as that. For example, this entire conversation started with "At the risk of setting up a strawman for people to punch down, try comparing how easy it is to do the equivalent of something like this".

And this became a discussion of straw men :) Because I could just as easily come up with "replace a range of numbers with data that is read from a database or from async function that then goes through the same transformations", and the result might not be in Python's favor.


It's not "twice as long" in any syntactic sense, and readability is easily fixed:

    Enumerable.Range(1,50)
        .Where(e => e % 4 == 0 && e % 3 == 0)
        .Skip(1)
        .Select(e => e + 1)

That's very understandable, it's clear what it does, and if your complaint is that dotnet prefers to name expressions like Skip rather than magic syntax, we can disagree on what make things readable and easy to maintain.


It's literally "twice as long" syntactically. 120 vs. 67 characters.

And again, you keep omitting the rest of the line. (Why?) What you should've written in response was:

  var y = Enumerable.Range(1,50)
      .Where(e => e % 4 == 0 && e % 3 == 0)
      .Skip(1)
      .Select(e => e + 1)
      .ToArray();
Compare:

  y = [t[1] for t in enumerate(range(1, 50, 4))
       if t[0] % 3 == 0][2:]
And (again), my complaint isn't about LINQ or numbers or these functions in particular. This is just a tiny one-liner to illustrate with one example. I could write a ton more. There's just stuff Python is better at, there's other stuff C# is better at, that's just a fact of life. I switch between them depending on what I'm doing.


There's not a lot of difference if you use the query syntax in C# (assuming you add an overload to Enumerable.Range() to take the skip) - only no-one uses that because it's ugly. Also really nice that the types are checked + shown by tooling, as is the syntax.

I use Python a lot for scripting - what it lacks in speed of development/runtime it gains in being more accessible to amateurs and having less "enterprise" style libraries (particularly with cryptographic libraries, MS abstract way too much whilst Python just has think wrappers around C). That makes Python a strong scripting language for me. PyCharm is really nice too.

For real work? C# is better as long as you have either VS or Rider. Really dislike the VS Code experience (these JS-based editors are slow and nowhere near as nice a Rider) so then I can understand why people would avoid it.


The ToArray is unneccessay, it's much more idiomatic dotnet to deal with IEnumerable all the way through.

The only meaningful difference in lengths is that C# doesn't have an Enumable.Range(start, stop, increment) overload but it's easy enough to write one, and then it'd be essentially the same length.


"Unnecessary"? You can't just change the problem! I was asking for the equivalent of some particular piece of code using a list, not a different one using a generator. Sometimes you want a generator, sometimes you want an array. In either language.


This is a silly argument, you're asking for a literal translation of a pythonic problem without allowing the idioms from the other languages.

If you were actually trying to solve the problem in dotnet, you'd almost certainly structure it as the Queryable result and then at the very end after composing run ToList, or ToArray or consume in something else that will enumerate it.

We can also shorten it further to:

    Enumerable.Range(1, 50)
        .Where(e => e % 12 == 1)
        .Skip(2)
        .ToList()
Now even including the ToList it's now just four basic steps:

Range, Filter, Skip, Enumerate.

Those are the very basics, all one line if wanted. It doesn't get much more basic than that, and I'd still argue it's easier for someone new to programming to see what's going on in the C# than the python example.

edit: realised the maths simplifies it even further.


The big problem is that while shorter, the Python statement itself looks obfuscated, confusing, and hard to read. C# is a bit longer but way clearer.

For me, that it's possible to write such ugly and hard to understand statements isn't an advantage of a language, it's a foot-gun.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

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

Search: