←back to thread

140 points ksec | 1 comments | | HN request time: 0s | source
Show context
simply-typed ◴[] No.41083880[source]
The fact IntelliSense and jump-to-source are supported at a very superficial level goes to show the heavy drawbacks of dynamic types.

Sorbet may fix things, but at that point, just use a language with more mature tooling around types, like Python or TypeScript.

Dynamic types offer dubious marginal benefits but bring tons of downsides. The demonstrations in this article reflect that.

replies(6): >>41083934 #>>41083947 #>>41084060 #>>41084088 #>>41084115 #>>41084491 #
adamtaylor_13 ◴[] No.41084060[source]
The problem is that Rails is the super power that keeps Ruby alive (in my personal opinion). I’d love to use a Typescript solution that has the power and opinionated style of Rails, but there’s nothing comparable. I think AdonisJS wants to be that, but it’s not battle-tested enough for me to feel comfortable relying on it for production projects.
replies(1): >>41090652 #
chris12321 ◴[] No.41090652[source]
It's really the other way around, Ruby is the superpower that makes Rails what it is. There are very few (if any) web frameworks comparable to Rails because Rails is only possible due to the dynamism and expressiveness provided by Ruby.
replies(1): >>41092223 #
adamtaylor_13 ◴[] No.41092223[source]
Can you provide some examples? At least from my point of view, Rails’s power comes from its opinionated convention over configuration approach and its batteries-included philosophy.

People talk about the DSLs and conciseness, but frankly those don’t make/break Rails for me.

I’m curious to know what part of Rails wouldn’t be possible in something like Javascript.

replies(1): >>41094805 #
chris12321 ◴[] No.41094805[source]
In terms of convention over configuration, Ruby's metaprogramming is crucial for the name-based class conventions that make Rails so convenient. For instance, if you have a class User with the attribute name, at runtime Rails dynamically adds methods to the User class, allowing you to do things like User.find_by_name("Alice"). Rails uses Ruby's metaprogramming capabilities to accomplish this.

The same is true for defining associations between models. Consider the following model:

   class User < ApplicationRecord
     belongs_to :organization
     scope :active, -> { where(active: true) }
   end
You mentioned that DSLs aren't important, but the DSL for defining associations is extremely convenient. Adding the belongs_to line defines numerous methods on the User class, allowing you to do things like User.last.organization. The scope line dynamically defines the active method, allowing you to call User.active, which executes the code in the provided block. There are also DSLs for defining routes and migrations, which are extremely important when using Rails.

Ruby's metaprogramming is also utilized in Rails controllers to load the correct code. For example, the index method in the UsersController knows to look for the views/users/index.html file because it can reflect on the method and the class to determine where to load the correct code using Rails' autoloader, Zeitwerk.

Ruby's open classes and monkey patching (something that should be done with extreme caution) allow ActiveSupport to add extremely useful methods to Ruby's base classes. This enables conveniences such as Date.today - 10.days or DateTime.now.beginning_of_day.

These are just a few examples that I can think of off the top of my head, but nearly every major convenience in Rails relies on the flexibility provided by Ruby. While it might be possible to reproduce many aspects of Rails in JavaScript, I don't believe you could replicate all of it with the same readability and intuitiveness that Rails offers.

replies(1): >>41101272 #
dmux ◴[] No.41101272{3}[source]
>In terms of convention over configuration, Ruby's metaprogramming is crucial for the name-based class conventions that make Rails so convenient. For instance, if you have a class User with the attribute name, at runtime Rails dynamically adds methods to the User class, allowing you to do things like User.find_by_name("Alice"). Rails uses Ruby's metaprogramming capabilities to accomplish this.

This can be accomplished in statically typed languages too. For example, Java has an ORM called Cayenne that generates models based on database tables. You can get similar functionality and ensure you're not accidentally calling something like `find_by_nam`

replies(1): >>41104477 #
1. chris12321 ◴[] No.41104477{4}[source]
ActiveRecord doesn't generate models based on database tables, it uses conventions on table and attribute names along with Ruby's metaprogramming capabilities to define behaviour on models automatically. From my understanding, Cayenne requires manual mapping of the database to your models, which is done via XML files that are either handwritten or generated by their GUI application and have to be regenerated on every database change. That's a far cry from the ease of use of ActiveRecord. How you value that ease of use versus your desire for static typing is up to you, but they’re not comparable from a functionality point of view.

And like I said above while you might be able to recreate some of Rails' functionality in other languages, you wouldn't be able to replicate all of it with the same fluidity and readability that you have in Rails