←back to thread

511 points mootrichard | 3 comments | | HN request time: 0.001s | source
Show context
setpatchaddress ◴[] No.23990944[source]
I'm really puzzled by the decision to use a separate file for this. The stated justification ("it doesn't require changing Ruby code") doesn't make sense, and my personal experience with languages with external type specifications is strongly negative. It's an unbelievable pain to keep multiple interface files in sync over time.

`.h` files are not something to emulate! External interfaces should be generated by tools where needed.

replies(5): >>23991001 #>>23991013 #>>23991258 #>>23991289 #>>23994203 #
rattray ◴[] No.23991258[source]
FWIW, you can use inline syntax with Sorbet[0], one of the two typecheckers that will work with the RBS format (the other being Steep, which does not have inline syntax).

Here's a full example, complete with a typo, based on the example in the blog post: https://bit.ly/3hMEMSp

Here's a truncated excerpt to get the basic idea across:

    # typed: true

    class Merchant
      extend T::Sig

      sig {returns(String)}
      attr_reader :name

      sig {returns(T::Array[Employee])}
      attr_reader :employees

      sig {params(token: String, name: String).void}
      def initialize(token, name)
        @token = token
        @name = name
      end

    end
Disclaimer, I used Sorbet while I was an employee at Stripe. I found it to be a terrific typechecker. It's also just absurdly fast (most of the time).

[0] https://sorbet.org

replies(4): >>23991351 #>>23991577 #>>23992070 #>>23995882 #
jrochkind1 ◴[] No.23992070[source]
OK, but if we're going to have .rbs, why not just modify the ruby syntax to allow .rbs-style types inline? Especially becuase .rbs already looks like class and method definitions without the bodies. So... just add the bodies.

    class Merchant
      attr_reader token: String
      attr_reader name: String
      attr_reader employees: Array[Employee]

      def initialize(token: String, name: String) -> void
         # actual method body
      end

      def each_employee: () { (Employee) -> void } -> void
                   | () -> Enumerator[Employee, void]
          # actual implementation body
      end
    end
It seems like they are trying to support existing competing work... but i'm not sure any ruby users actually want that. I prefer this .rbs to sorbet all around, and would prefer it inline.
replies(1): >>23992156 #
rattray ◴[] No.23992156[source]
> why not just modify the ruby syntax

The Ruby syntax is too complicated to allow for changes like this to be backwards-compatible.

For example, `attr_reader token: String` is valid ruby today – that's the same as `attr_reader(:token => String)` which somebody might be doing in the wild, since you can override `def self.attr_reader`.

Similarly, `def initialize(token: String` clashes with the definition of keyword arguments.

replies(1): >>23992192 #
jrochkind1 ◴[] No.23992192[source]
doh! good point.

I am not able to spin that into "And besides it's better to force it to be in two files anyway!", I don't think it is, but I guess it's not so easy to do different.

replies(2): >>23992807 #>>23995245 #
TylerE ◴[] No.23992807[source]
Header files suck. Anything is better than a separate file.
replies(1): >>23993023 #
1. dragonwriter ◴[] No.23993023{3}[source]
> Anything is better than a separate file.

I dunno. Massive breakages of backward compatibility in an established language may not be better than that.

replies(1): >>23993211 #
2. etxm ◴[] No.23993211[source]
It is a major version change, right? It seems like the best time to introduce some breaking changes for the betterment of the language.
replies(1): >>23993445 #
3. djur ◴[] No.23993445[source]
Syntax changes of this magnitude would make the Python 3 migration timeline look quick and painless.