Remix.run Logo
usrbinenv 13 hours ago

I constantly feel like inferior languages are picked up, while superior languages are discarded. It's almost as if the universe had a law: "inferior technology is always preferred no matter how hard you seethe".

Examples:

  * Python preferred over Ruby
  * TypeScript preferred over Dart or even JavaScript (which is fine and, as a bonus, doesn't require compilation step like TS)
  * Go is preferred over Crystal and D.
While Python, TypeScript and Go are quite alright, there is no doubt in my mind that their alternatives are absolutely superior as languages. Yes, in case of Dart, Crystal and D the ecosystem doesn't have the abundance of well-tested libraries, but as languages they are simply better. The Go argument that it's popular because it's simpler is absurd in the sense that no one really forces you to write complex code and use classes or other advanced OOP features in D.
pjmlp 5 hours ago | parent | next [-]

What pains me in Python adoption, beyond its use as Perl replacement, is that we have so much better dynamic languages with advanced JIT implementations, but have to reach out writing extensions in native languages instead.

At least Python as DSL for GPU JIT compilers is a thing now.

Yes, I know about PyPy in the corner looking for attention.

creata 3 hours ago | parent [-]

> we have so much better dynamic languages with advanced JIT implementations

What are some of these better languages that you're referring to? (The usual dynamic language JITs I hear people praise are LuaJIT and Chez. And V8. And the JVM?)

pjmlp an hour ago | parent | next [-]

Smalltalk, Self, whose research lead to Hotspot and V8, Common Lisp.

And the usual, in Python everything is dynamic, well it is even more so in an image based live coding environment, where any break into the debugger, with code changes and resume execution can come back to a complete different world.

Additionally there are features like Smalltalk become: message, where two objects can change places everywhere they are used in the image, and current execution.

esafak an hour ago | parent | prev [-]

I'd suggest F#, Clojure, Elixir, Scala, and TS, if that counts.

old-gregg 12 hours ago | parent | prev | next [-]

Languages do not matter as much as you think. Ecosystems are everything. Twice in my life I started companies (the first one took all my life savings) and in both cases the right call was what you called an "inferior language".

I actually liked D very much, and WB had been a personal hero of mine when I was in college. But I am not betting my career on an ecosystem built around by a single brilliant guy. For high-stakes projects, a wise decision is building on a platform with several deep-pocketed backers.

And for toy/personal projects... do you even need a language anymore? Just ask your favorite LLM to generate you an executable which does what you want (partially joking here).

WalterBright 11 hours ago | parent | next [-]

D's ImportC feature makes it super easy to access C libraries from D code. That means D fits right in with a C ecosystem, as it's no longer necessary to attempt to translate the .h files into D.

It's not perfect, as some people cannot resist using the C preprocessor for some bizarre constructions.

I used to write those bizarre things myself in C, and was proud of my work. But one day I decided to remove them all, and the code was better.

giancarlostoro 10 hours ago | parent | next [-]

One area where Go, C# and Rust beat D is packages in a few different ways.

For C# Microsoft eventually embraced NuGet their package manager, and used it to put core packages that don't need to be fully available OOTB but can then benefit from frequent updates on a per project basis as opposed to updating the entire language runtime.

For Go it was the out of the box packages, like if I want to make a website, I can pull in net/http and their templating packages that come out of the box with Go, maybe a reasonably simple core maintainer package or packages that go into Dub would be a strong selling point. Right now Vibe.d is the only option for web dev, but there's no reason a much simpler web server couldn't exist.

For Rust, I just really love Cargo, I think its one of the nicest package managers I've ever used.

The other thing that would really help D is if something significant is built around D, whether it be a framework (like what Rails did for Ruby) or some major application that needs D to function at its core and is used by many, this could be a groundbreaking modern IDE, or anything really, a database that uses the best bits and pieces of D to scale, or even a really rich cross-platform GUI stack (my kingdom for std.gui to be a thing in D, and reasonably exhaustive).

I wish I had unlimited time and money, I would invest it in D. Alas, I'm not a language maintainer, just a guy who loves really good tools.

kev009 10 hours ago | parent | prev | next [-]

It seems like the parent was trying to paint a situation of you being a bottleneck to success. It seems a bit Schrödinger's BFDL though.. is Linus a bottleneck to the most used server operating system? Did Guido hold back Python? The existence of the GDC and LDC compilers torpedoes toolchain concerns.. I'd be more worried about Java or Golang suffering from some eventual corporate buffoonery.

To the parent's point of startups, betting the farm on something like a particular language out of some sense of superiority might mean you are not focusing on the right problems. But if the founders happen to know a less widely used tool it doesn't seem inappropriate either. The type of employee that can drive a startup or a big tech project forward is not going to be thwarted by a language, and they might find something new to learn fun.

zerr 9 hours ago | parent | prev | next [-]

Any plans to implement Swift like C++ interop?

ofrzeta 10 hours ago | parent | prev [-]

It would be great if D supported something like OpenAPI generator https://github.com/OpenAPITools/openapi-generator

Maybe it exists and I am just ignorant but it doesn't seem to be in the list of supported languages.

pjmlp 5 hours ago | parent | prev [-]

I belive asking the favorite LLM to generate an executable will be the future, just like high level languages drove Assembly development into a niche.

Yes it isn't here today, just like it took several decades for optimizing compiler backends to do a very good job.

In fact one of the reasons why Matt Goldbolt created Compiler Explorer was to have a way to settle arguments he was having in the games industry.

Koshkin 30 minutes ago | parent [-]

> LLM to generate an executable

... and the job of a programmer will be to explain, in as precise terms as possible, what they need the executable to do. (Reminds me of the idea of programming based on a natural language.)

esafak 12 hours ago | parent | prev | next [-]

https://en.wikipedia.org/wiki/Worse_is_better

realharo 6 hours ago | parent | prev | next [-]

Dart is much worse than TypeScript. The over-reliance on codegen for the most simple things (e.g. https://pub.dev/packages/freezed#primary-constructors), the lack of expressiveness of the type system (it only got sum types very recently), and a lot of other little annoyances are ever present when having to write Dart.

ofrzeta 10 hours ago | parent | prev | next [-]

It's quite subjective what you consider to be better. Is Ruby better than Python? Maybe so, but Ruby only ever had one killer app that is Rails while Python has a vast ecosystem. Is Crystal better than Go? Maybe so, but Go ist just so much more mature (plus the ecosystem argument).

GoblinSlayer 7 hours ago | parent | prev | next [-]

It's scary to not have type checks in JavaScript. I do them by eyeballing the code, but ugh.

Also all languages you mentioned support complex code and OOP.

vips7L an hour ago | parent [-]

Code can be complex in any language. TypeScript itself can produce some really complex types. OOP isn’t a bad thing either; it’s just a tool.

zem 7 hours ago | parent | prev | next [-]

speaking of typescript and dart, the language i was really rooting for in that niche was haxe. wish it had gotten more mainstream.

3 hours ago | parent [-]
[deleted]
Demiurge 12 hours ago | parent | prev [-]

> Python preferred over Ruby

... Perhaps what you're describing is having a niche opinion. If you had some opinions, like a preference for "Everything must be done in as many ways as possible with funky characters" or "I hate indentation", it would certainly seem that the world is against you. But, perhaps, you just really smart and can remember the intention of all the complicated code you wrote a year ago, so you don't even need to write comments, and thats great. However, being special does not mean that some technolgoy is objectively inferior, unless you can actually come up with a provably objective metric.

Overall, the technology that is there, solving most of the problems for most of the cases is the technology that is superior, by the law of the universe, not the other way around.

I don't agree with any of your examples, but I have my own, like Pascal is a better language than C, by many metrics. I can also accept that C, is what people who invented unix, also invented. And that makes Pascal inferior to C, now, as choice for any project that requires that you hire embedded software developers. That's what the universe decided.

kouteiheika 11 hours ago | parent [-]

> "Everything must be done in as many ways as possible with funky characters"

Are you sure you're not talking about Perl here? Because there are very few "funky characters" in Ruby and code written in it tends to be very readable, more so than Python in many cases.

I agree with OP. While Python is not a bad language, Ruby is a better language in general, and I'm reminded of it every time I have to work in Python (which is pretty often nowadays, due to Python's dominance in ML ).

I can give many examples as to why, but here's a quick toy example to show off the difference in philosophy between Ruby and Python. You have a list of numbers, you want to keep only odd numbers, sort them, and convert them to a string where each number is separated by comma. Here's the Ruby code:

    xs = [12, 3, 5, 8, 7, 10, 1, 4]
    ys = xs.filter { |x| x.odd? }.sort.join(", ")
Now let's do the same in Python:

    xs = [12, 3, 5, 8, 7, 10, 1, 4]
    ys = [x for x in xs if x % 2 != 0]
    ys.sort()
    ys = ", ".join(str(y) for y in ys)
Or alternatively in a single line (but in more complex cases this gets extremely unwieldy since, unlike Ruby, Python forces you to nest these, so you can't write nice pipelines that read top-to-bottom and left-to-right):

    xs = [12, 3, 5, 8, 7, 10, 1, 4]
    ys = ", ".join(str(y) for y in sorted(x for x in xs if x % 2 != 0))
And this matches my experience pretty well. Things I can do in Ruby in one line usually take two or three lines in Python, are more awkward to write and are less readable.
Demiurge an hour ago | parent | next [-]

Ruby is in the running, so to speak, so of course that means there are thousands of people who agree with you. I'm not one of them. The fact that Ruby did not take of as much as Python did, even though there was all that RnR hype, is a testament to that. I don't think your examples are readable. What is |x| x.odd? ? (question mark pun intended) This is just "cleverness". I, personally, want my programming language to use method to use a keyword like "is" instead of operand?[question mark operator]

abenga 9 hours ago | parent | prev | next [-]

To a beginner who is used to ordinary imperative languages, that Ruby line is extremely difficult to understand. Is `.filter` a method or a property of `xs`? Is `{ |x| x.odd? }` an argument to a method or just a statement that comes after `xs.filter`? If it is passed to `.filter`, why does it not have parentheses around it but the `", "` passed to `join` does?

This all makes sense to a person who knows the language a lot, but wrinkles the brain of a newcomer. Too many concepts to juggle in order to understand. On the other hand, the Python one reads quite easily, even if you may have to go right to left.

usrbinenv 9 hours ago | parent | next [-]

The only difficulty in Ruby code is the block notation. Even then, it is very similar to constructs in JavaScript, Go, D and a number of other languages -- the only difference form JS would be that instead of `(x) => ...` you write `{ |x| ... }`.

Questions such as

> why does it not have parentheses around it but the `", "` passed to `join` does?

would be exactly the same for JavaScript, Go or D. Ruby has the best syntax with regards to blocks/lambdas/closures.

Qem 2 hours ago | parent | next [-]

> Ruby has the best syntax with regards to blocks/lambdas/closures.

A bit of Smalltalk shining through Ruby.

abenga 8 hours ago | parent | prev [-]

I don't know much Ruby outside of a few toy examples I wrote a long time ago. For most languages, there would be parentheses around objects you pass to functions, like `.filter({|x| x.odd? })`. This lends some consistency and makes it easy (for me at least) to understand that an anonymous function is passed to `filter`. Just separating it using spaces feels like Bash, something I find difficult to write anything slightly complicated in.

creata 7 hours ago | parent [-]

Lua, Haskell, ML, plenty of other languages where one-argument functions don't need parentheses. I think it makes a lot of code more readable.

abenga 6 hours ago | parent [-]

All not-exactly-popular languages.

creata 6 hours ago | parent [-]

Maybe relative to juggernauts like C or Java. But Lua is pretty widely used.

Defletter 2 hours ago | parent [-]

Kotlin too

kouteiheika 8 hours ago | parent | prev | next [-]

> To a beginner who is used to ordinary imperative languages, that Ruby line is extremely difficult to understand.

I don't understand this argument. You are a beginner only for a tiny fraction of your time using a given programming language. Why are we optimizing a programming language for people who don't know it, instead of optimizing it for people who actually program in it?

abenga 6 hours ago | parent [-]

> Why are we optimizing a programming language for people who don't know it, instead of optimizing it for people who actually program in it?

Everyone who actually programs in a language was once a person who didn't know it. Languages which optimize for succinct terseness might be powerful once you master them, but they will never enter mainstream use, which I guess is not necessarily the aim.

creata 7 hours ago | parent | prev [-]

The Ruby syntax doesn't seem that different to many other languages. For example:

    xs.filter(x => x & 1).sort().join(", ") // JavaScript

    xs & filter odd & sort & map show & intercalate ", " -- Haskell
Python seems to be the odd one out. Imo, its list comprehensions are confusing as hell to "newcomers". For example, when a list comprehension has multiple `for`s, what order are they nested in?
quietbritishjim 2 hours ago | parent | next [-]

> ... confusing as hell to "newcomers". For example, when a list comprehension has multiple `for`s, what order are they nested in?

I get that this is just a rhetorical question to make a point about newcomers, and I do agree it's not immediately obvious, but for the record: you can imagine any "if"s and "for"s in a list comprehension are nested statements in the same order. So, for example, this:

   l = [
      y.foo()
      for x in my_list
      if x.blah() > 7
      for y in x.ys()
   ]
Is equivalent to this:

   l = []
   for x in my_list:
       if x.blah() > 7:
           for y in x.ys():
               l.append(y.foo())
So the least comprehension is basically in left to right order with the one exception of the actual expression to be added to the list (like y.foo() in the example above).
creata 2 hours ago | parent [-]

Yeah, I know, I know. But I imagine many people would mentally want to bracket [e for x in xs for y in ys] like [(e for x in xs) for y in ys] and thus conclude that y is the outer loop.

abenga 6 hours ago | parent | prev [-]

Those both seem a little bit more consistent than the Ruby example, however. To understand the JS example for example, you only need know that to call a method on an object, you do `object.method(arguments)`, and this is chained in a straightforward manner, with methods called on the returned values left to right. Ditto for the Haskell example. Maybe the Ruby one does the same thing, but even in this extremely simple example, we still have two different ways of doing the same thing.

For Python, you don't really have to use list comprehensions in the place of multiple for loops, you can sacrifice the brevity afforded to write the same thing in a more easily understandable fashion.

7 hours ago | parent | prev [-]
[deleted]