Settings

Theme

Ruby 3.0 Preview 1

ruby-lang.org

622 points by polysaturate 5 years ago · 206 comments

Reader

_odey 5 years ago

My thoughts:

- RBS: meh... might get more useful in the future (in 2-5 years maybe).

- Ractor: Wohooo! I'm writing a DAG library where I was thinking of implementing something like this, good to know I can use it and get real parallelism on top.

- Scheduler: :shrug: don't know about this one, might be relevant with future concurrent ruby code, any ideas?

- Rightward assignment: it's a bit awkward but I see the use case, just wish we had the pipe operator too like in Elixir.

- Endless method: this one is cute, I love it!

- Find pattern: oh boy, code reviews are going to be interesting now!

- Hash#except: yes, definitely a welcome one.

- Memory view: if this helps with numpy style gems it will be great!

- `send(:"do_#{ meth }", ...)`: don't do meth kids! (it's a joke!)... seems like a reasonable feature.

- `order of backtrace had been reversed`: good! it was confusing...

- Promote default gems to bundled gems (rexml): I like this one, if only nokogiri was a stdlib gem or part of core, imagine how much time would be saved instead of having to compile it every time in a `bundle install`.

- `Promote stdlib to default gems`: what does this mean? Do I now have to add `gem "securerandom"` to Gemfiles instead of having it by default and just needing to require it?

- Mjit improvements: can't wait to try it!

Overall, I'm delighted!

reader_mode 5 years ago

>Rightward assignment statement is added. >fib(10) => x

This is exactly the kind of stuff I hated when I had to work with ruby in my last gig and why I will never accept a job using it again - soo many pointless and inconsistent ways to do the same thing ... they have method aliases for collection operations like map/filter in standard library ! .NET went with non-standard SQL-like names (select/where) and I'm not a fan but at least they made their choice and stuck with it. And it's inconsistent all over the place - like '!' postfix means "operation mutates the object" in std lib BUT in rails it means the operation will raise an exception and not return an error code.

Now they add a pointless operator that means completely different thing in other languages to throw off even more people.

It's just a hell of a language to maintain someone else's code in.

  • JohnBooty 5 years ago

    I love Ruby, but I agree with you about disliking that kind of thing.

    I've done Ruby since 2014 or so at a few shops. My general anecdotal experience:

    - Lone Ruby coders often use a lot of that cutesy/obscure/dense stuff.

    - Teams of people writing Ruby, with healthy code review practices, tend to value simple, easy-to-read Ruby.

    - A lot of Popular Ruby gems (and projects at aforementioned Ruby shops) have Rubocop-based style guides. Rubocop has some very strict ideas about Ruby coding style. The defaults are mostly quite sane and it's easy to disable/customize the ones you disagree with.

    Not making excuses for some of the more florid parts of Ruby's syntax and stdlib, but in practice I do find things are manageable!

  • d3nj4l 5 years ago

    But that's what I love about Ruby! There's so many great ways to express logic, making Ruby a language that really rewards exploration. Of course, when working with a team on a production application, you'd set up standards everyone can agree on and understand with rubocop or prettier-rb (which I loathe and will not touch with a 10-foot long pole for my personal projects). That's also great for onboarding newcomers - they can get their feet wet with "standard" ruby at work, and then experiment with it more deeply in their own time, finding themselves in the ways they choose to express their logic. And then, every now and then if you find something really elegant and beautiful in your own exploration, you can introduce it to your team and add it to your team's style if they all agree on it. Between a language that makes all the choices for you, and a language that gives you the freedom to choose how you do things, I'd pick the latter nine times out of ten: at least in the latter, you can restrict yourself from the more wild stuff, but in the former you're forced into a narrow band of choices. I sure didn't ask for right assign, but I'll be trying it out in my personal projects!

    • bb88 5 years ago

      > you'd set up standards everyone can agree on and understand with rubocop or prettier-rb

      Things like that just often lead to bikeshedding. And then worse, powerful voices may approve ideas that work for them and not everyone else, or even more worse crippling a language to be too safe or bland to be truly useful.

      I got into an argument a couple weeks ago whether an unprotected eval() in python should make it's way into production code of a fortune 500 company. The coder's argument was that, "Well the language has it so why not use it?"

      "Because with great power, comes great responsibility..."

      • d3nj4l 5 years ago

        That's a problem with culture, not with the language. You can't say "you can get into accidents if you drive a car, so you're not allowed to drive"; you try to fix it by setting rules into place. At any rate, if you don't like bikeshedding, there's great, well appreciated standards in place for ruby which you can take up as-is: there's AirBnB, standard-rb/ prettier-rb and rubocop's default config. No bikeshedding involved, pick one and run with it

        • bb88 5 years ago

          Which culture are you talking about? Company culture or programming culture?

          My understanding was the general bikeshedding around formatting was the reason gofmt won for golang. That seems to hint the problem is a programming wide culture. Just in the same historical context programmers have had around tabs vs spaces...

      • riffraff 5 years ago

        > And then worse, powerful voices may approve ideas that work for them and not everyone else, or even more worse crippling a language to be too safe or bland to be truly useful.

        but that same thing will happen if the powerful voices are the ones taking the decisions for the whole language.

  • strken 5 years ago

    The thing that most annoyed me about Rails (not Ruby) was that

        users.size
        users.length
        users.count
    
    are all valid, all useful, all have different meanings, are all present in plain Ruby but with different meanings, and contain absolutely no information about what they do.

    For reference, .length loads everything and gets the length of the collection, .count runs a SQL COUNT query, and .size uses length if the query has already been run and .count if it hasn't.

    • nsomaru 5 years ago

      So why would you not just default to always using .size?

      • adrusi 5 years ago

        You usually want to know when you're hitting the database. "Hit the database if the value isn't cached" is useful behavior, but should probably be telegraphed a bit more precisely than just the word "size".

        • mosselman 5 years ago

          “size” is fine. The person you are responding to is trying to say that complaining about multiple options is a bit strange as you can just use one option. Why is it an issue that other options exist? Who cares. There are synonyms for English words as well, is that an issue as well?

          • tinus_hn 5 years ago

            They are not synonyms, they mean slightly different things. And that is the problem.

            Because for small datasets the difference doesn’t matter this results in beginner programmers choosing randomly, which 2/3 of time is the wrong choice.

            • mosselman 5 years ago

              So if 'length' was the only option and I'd have to do ActiveRecord::Base.connection.execute('SELECT count(*) FROM users').values.first or something it would all be fine?

              • strken 5 years ago

                Other ORMs separate building the query from executing the query, which is less ergonomic but more explicit. Drawing on Rust, https://diesel.rs/ shows how this approach would work:

                    users.select(count_star()).first(&connection)
                
                which is really just a cleaned-up version of your suggestion.

                Of course, you could imagine an ActiveRecord-like API to make this nicer:

                    User.first{|t| t.count}
                    User.first{|t| t.count}.execute!
                    User.execute{|t| t.count}.values.first
                    # ...etc.
                
                but the underlying problem is that building the query and executing the query are two discrete steps, Rails streamlines them instead of making the separation obvious, and when a system hides complexity it becomes harder to know what it's really doing.
          • adrusi 5 years ago

            "size" is not fine. If I'm conditionally hitting the database, I want that to be as explicit as possible.

      • pawelduda 5 years ago

        There are no guarantees that the count will remain correct after the first run of the query.

    • majormajor 5 years ago

      I learned Ruby by itself and only worked on Rails code later... so I've had a lot fewer core Ruby complaints then most.

      But Rails has definitely become a PR problem for the language in terms of how many complaints like this it leads to.

    • joelbluminator 5 years ago

      Ugh yes I don't like this as well. Even if they're all useful, I'd do it with one method that accepts some optional arguments, this is unnecessarily confusing.

  • gorgoiler 5 years ago

    I would never share a Ruby code base with anyone either. It’s like issuing kindergartners a can of silly string and asking them to be sensible with it.

    I consider myself a sensible developer, but even I’ve had some childish moments with Ruby: doing something I thought was clever and productive but which really just made my code inscrutable and unmaintainable...

    ...by other people. The flip side is I can just about figure out what I was trying to do when I read my own code: enough so that I still always use Ruby for personal projects.

    Ruby is just too much fun and critically, to date, it’s the only language where I can write a page of code at the same speed I am thinking. It also usually executes first time without any errors, which is a joyous thing.

    I am not claiming to be some kind of 10x uber hacker. Ruby just happens to be an incredibly wonderful language for thinking aloud with code.

    • joelbluminator 5 years ago

      Why wouldn't you share your Ruby code with others? As a Ruby developer I an assure you, us Rubyists can work and understand each other's code.

      • gorgoiler 5 years ago

        To be frank, the language just isn’t boring enough.

        In my experience, a company’s code should be like the style of English used in an instruction manual. It should clearly and plainly express the business logic behind the company’s mission.

        Ruby is more like writing poetry. There’s nothing stopping one from writing boring, unambiguous, clear code in Ruby of course. As a Ruby developer, I’m sure your code looks very clear.

        The reality is that other languages make it easier to enforce clarity. See gofmt for example, which standardizes Golang’s formatting, taking one more axis of “creativity” away from the less disciplined developers.

        • joelbluminator 5 years ago

          I second adding Rubocop. But sure, Ruby has a way richer syntax and a higher freedom degree than a language like Go. It's part of what makes Ruby what it is. If high degree of freedom isn't something you want Ruby isn't a good choice.

        • neilwilson 5 years ago

          Add rubocop to your editor.

          You can get it to discipline you as much or as little as you like.

  • philwelch 5 years ago

    Ruby can also be an extremely decision-fatiguing language to write code in.

  • steveklabnik 5 years ago

    ! means “dangerous”, not mutation. Yes, that’s how it plays out because it is one kind of danger, but it’s not inconsistent.

    • choward 5 years ago

      It's also not supposed to be used unless you have another method with the same name.

      Also, what kind of danger are we talking here? I consider mutation dangerous. Danger could also mean it has side effects or that it can raise an error.

      I wouldn't call it inconsistent but I would call it arbitrary.

      I would rather just name the method "#{base_method}_#{why_its_dangerous}". For example take ActiveRecord::Base#save and #save!

      #save mutates and I would consider that dangerous. #save! can raise an error. I would rather name #save! as #save_or_raise_if_invalid. I know it doesn't look as pretty and takes longer to type but I really don't care. Then again, I'm not a big fan of exceptions so I would never call it.

      • steveklabnik 5 years ago

        Original source here, by the way: https://www.ruby-forum.com/t/conventions-in-ruby-and-the-pri...

        All of those things are "dangerous" in this sense.

        It is arbitrary, but that's how Ruby works; there's a gray area shared understanding of concepts. The "principle of least surprise" is literally about Matz, and Matz alone. Yes, something may be surprising to you, or not, but it's not about you. This shared taste/understandings/whatever is just how convention works. (Or at least, it did when I was involved with Ruby; it's been a couple of years so I'm out of touch!)

        • choward 5 years ago

          I have also strayed away from Ruby so I'm out of touch too. The arbitrariness helped get me into Ruby and helped get me out. It's cool if that's your sort of thing but as I get older I'm starting to dislike arbitrary things more and more.

          Anyway, I didn't realize who I was replying to when I replied to your first comment. I've seen a few of your presentations and read a lot of your work and I'm a fan.

          • steveklabnik 5 years ago

            I think we followed similar paths; I still love Ruby but my tastes have changed. Rails is still really hard to beat in its area though.

            Thank you!

          • joelbluminator 5 years ago

            I think we're all really great in cherry-picking something lacking in a language and then describing the whole eco-system as bad. What language are you using now? Were there seriously no bad design decisions made in said language?

  • jrumbut 5 years ago

    I love all that stuff in Ruby to-date (used in it's appropriate place, following convention, etc) but the rightward assignment feels useless to me.

    I have no idea why the few languages that allow it do so. I've never wanted it and I can't imagine it makes parsing simpler in a language where you are sometimes compiling code at runtime and where parsing is already pretty wild.

    I've said this before and been wrong so let's hope this turns out to have excellent use cases.

  • levi0214 5 years ago

    Totally agree.Different approaches to the same thing won't add points to the language.

    P.S. the 'endless method definition' is meaningless, too.

    > def square(x) = x * x

    The original reason of this proposal was:

    > Ruby syntax is full of “end”s. I’m paranoid that the ends end Ruby. I hope Ruby is endless. --mame (Yusuke Endoh)

    It sounds like "let's add a new syntax for lisp because it has too many brackets"

    • shakna 5 years ago

      > It sounds like "let's add a new syntax for lisp because it has too many brackets"

      You'll find wisp [0] implemented for several of the larger Schemes. Often because the rationale for adding another syntax can be more nuanced and actually benefitial than a quick joke. [1]

      Whilst you're right that caution absolutely applies when modifying a language's syntax, there may be a case for it that reduces friction for the programmer. The change might have been proposed with a joke. I doubt the entire rationale ended there, however.

      [0] https://srfi.schemers.org/srfi-119/srfi-119.html

      [1] https://srfi.schemers.org/srfi-110/srfi-110.html#rationale

    • nitrogen 5 years ago

      This is a feature present in Kotlin, and it's useful for mathematical functions and simple-but-not-trivial getters.

  • wrp 5 years ago

    Ruby has been referred to as Smalltalk meets Perl, and the problem of dealing with other people's code is one of the main things that kept me in the past from using Perl on text processing projects. The problem of collaborating in Perl was lessened a lot by adhering to Damian Conway's Perl Best Practices. Is there anything similar for Ruby?

    • burlesona 5 years ago

      Rubocop and you're done. It's the first thing I'd add to any team project just because life's too short for an inconsistent codebase.

      • jherdman 5 years ago

        This. Rubocop is first class. I'm just flat out done bikeshedding in code. If I'm writing JS, it's an ESLint + Prettier combo — or whatever your taste is, I just don't care. Let's write code and let the machine deal with making sure it isn't too ugly.

    • ashtonkem 5 years ago

      Ruby’s heavier use of key words rather than symbols saves it from the worst of Perl.

      Yes, there’s still some symbols, but nowhere near as many.

  • cageface 5 years ago

    In a sense Ruby is sort of a cleaned up Perl but maybe not cleaned up enough.

    I fell totally in love with it almost 20 years ago but these days I think we have better languages to choose from even if their ecosystems aren't always as rich.

    • cutler 5 years ago

      You mean like Dart and Go? For expressivity I'll stick with dirty old Ruby, thanks.

      • cageface 5 years ago

        Ruby is expressive and makes for great short demos but becomes a nightmare to maintain in larger codebases with dynamic typing & implicit imports.

  • chrisoverzero 5 years ago

    >.NET went with non-standard SQL-like names (select/where) […]

    Which names do you believe are standard?

    • rpastuszak 5 years ago

      Arguably, select/where are less familiar than map/filter to many. I'm not saying that either is a standard, but I can imagine the confusion if you come from say, JS background.

      • fomine3 5 years ago

        To be fair, map/filter wasn't so popular like now when C# 3.0 (released in 2008) was designed.

    • philwelch 5 years ago

      Not who you’re responding to but from context I would assume map/filter, as he said.

    • EdwardDiego 5 years ago

      `where` is intuitive as a synonym for `filter`, but it's the `select` that always threw me as a synonym for `map`.

      I get that they're trying to expose an SQL-like API, but yeah, map is always about mutation, but `select`only does mutation sometimes in SQL.

      • monadic2 5 years ago

        Map doesn't mutate, it returns the result of applying a function to the (possibly immutable) value. I believe you can also, say, `select icolumn * 2 from table`, where `icolumn * 2` provides precisely the same functionality as the function passed to a map.

      • jen20 5 years ago

        `Where` at least answers the question "does filter _keep_ the things matching the predicate or _remove_ the things matching the predicate" - my pet hate with the .NET naming is `SelectMany` over `flatmap`.

  • crehn 5 years ago

    Happy someone else echoes my sentiment too, especially when Ruby seems to be beloved by everyone around. So many ways of doing the same thing; unnecessary cognitive burden for both reading and writing.

    • dmix 5 years ago

      Best practices are extremely common in Ruby. Something I long missed writing JS which only came about as the language started to really mature with ES5/6. Ruby seemed sufficiently mature and sufficiently best practiced in basic training and widespread usage where it wasn’t a problem.

      It’s not anything like C++ or C where the whole coding practice and culture changes depending on your framework (like using Unreal or doing Linux programming). The best practices were the same across the board.

      Basically my experience with writing it for a decade doesn’t match these critiques. The quirks in Rails were easily ironed out among intermediate developers. It’s not like it requires advanced programming knowledge to just do what everyone else is doing, which is often share in best practice documents and popular libraries/tutorials/books or (less so) rubocop style plugins.

eddietejeda 5 years ago

If you interested in seeing how the 3x3 initiative* has come along, here are the benchmarks so far: https://github.com/mame/optcarrot#readme

Personally, I am very excited for this release.

* Matz's goal to get Ruby 3 to be 3x faster than Ruby 2.

--

@sosodev Thanks for the updated info!

  • sosodev 5 years ago

    That README isn’t up to date. The benchmark has seen significant performance improvements since then.

    https://benchmark-driver.github.io/benchmarks/optcarrot/comm...

  • czbond 5 years ago

    I have been out of the ecosystem for a while, but use Ruby frequently. So the 3x3 is coming along? More up to date places I could see benchmarks or similar?

    Note: I have been using Roda with Ruby 2 and it is pretty fast. Can't wait to see what it would be with 3x3.

  • thatguyagain 5 years ago

    This might be a bit of a novice question, but will this affect the initializations of ActiveRecord objects in Rails anything?

    For example, processing a large CSV file and inserting new rows in a database from it has always been extremely slow using Ruby/Rails unless you basically just write raw SQL that copies from the CSV and don't do any initializations of Rails models, #create, etc. I wonder if this will improve these things at all, but my guess is that it has to do with memory usage and not the speed of Ruby?

rco8786 5 years ago

This is all great stuff. I’m rather meh on RBS, mainly because separating types from code is less than ideal but I like the potential here.

But the right hand assignment operator. What on earth. Nobody asked for that and nobody wants it. Why.

  • inopinatus 5 years ago

    Ruby already had a sort of limited form of rightward assignment, in exception rescue:

        begin
          #... do something
        rescue StandardError => ex
          #... handle exception
        end
    
    The ex here can be any assignment expression, it's not just a lexical variable. So you could already do this:

        class Guru
          def meditate=(exception)
            puts "caught #{exception.inspect}"
          end
        end
    
        # later ...
        rescue OutOfCheeseError => Guru.new.meditate
    
    i.e. creating a nice opportunity for passing error handlers around as an argument; or, this worrying idea:

        rescue TransactionError => Thread.current[:exception]
    
    and now I'm afraid you can do this:

        Cat = Struct.new(:name) do
          class << self
            def all() = @all ||= Set.new
            def adopt=(...)
              all << new(...)
            end
          end
        end
    
        "Astrid" => Cat.adopt
    • rco8786 5 years ago

      Oh the error handler example is kinda cool, especially paired with inline rescues

          def my_method
              .. code ..
          rescue FileNotFoundError => FileNotFoundHandler
          rescue StandardError => StandardErrorHandler
          end
      
      But yea, as is so often the case with ruby, you can really shoot yourself if you try hard enough :P
  • djur 5 years ago

    What's strange is that it seems to have been an offshoot of the pipeline operator (|>) work from last year[1], which was originally proposed as having an assignment syntax like

      foo |> bar(20) |> (x)
    
    where x is assigned to. People didn't like that syntax, and there were issues with = being higher precedence than |> [2]. This new right-assignment operator was created in response to that [3].

    The weird thing is that the pipeline operator got killed, so the original reason for r-assign no longer exists. It looks to me like there's just some people on the Ruby team who took a shine to it.

    [1]: https://bugs.ruby-lang.org/issues/15799 [2]: https://bugs.ruby-lang.org/issues/15799#note-22 [3]: https://bugs.ruby-lang.org/issues/15921

  • burlesona 5 years ago

    The examples given were all things that would be nice to do in the REPL. What I don’t understand is why not just define it in the repl, then, like ‘_’.

    • jaynetics 5 years ago

      Because changing or pre-processing the language syntax is far beyond the scope of any REPL. Assigning the latest return value to a variable named '_' is very straightforward and does not require dealing with the syntax.

phaedryx 5 years ago

I have mixed feelings.

I'm not a fan of rightward assignment because I don't see much value and now the => operator has even more meanings.

I'm not a fan of endless methods because how lazy do you have to be to not want to type 'end'? My editor does it for me automatically. Now there is even more parsing.

  • dmix 5 years ago

    JS has already adopted the endless style and it’s obvious when to use it and where a single line adds needless complexity. It’s really an overrated barrier to entry with a high return value in code simplicity (particularly aesthetically, which goes a long way with Ruby).

    I have no comment on the rightward bit though. That is more... radical. Until I see how it is adopted generally.

  • levi0214 5 years ago

    Completely unnecessary syntax.

    It does nothing but add complexity.

d2161 5 years ago

You can test your heroku app on the new ruby 3 preview already! (https://devcenter.heroku.com/changelog-items/1889)

shadykiller 5 years ago

I love Ruby and great to see Ruby love on hacker news. Just curious on how popular it is in the hacker news community ?

  • chrisseaton 5 years ago

    > Just curious on how popular it is in the hacker news community ?

    Seems to be well represented by successful companies here.

    https://www.ycombinator.com/topcompanies/

  • swat535 5 years ago

    You know I've long stopped caring about how popular a language is in the community.

    As I get older the question I ask myself is do I honestly enjoy using it? If the answer is yes, then I put it in my programming toolbox and ignore the hype.

    • tartoran 5 years ago

      Love the attitude, but sometimes it is not beneficial to stick to a programming language that you simply like if you need to make a living out of it. If a programming language is decreasing in popularity it becomes harder to get work. If a programming language is not popular but it has a niche and one is in that niche then it's all good.

    • cutler 5 years ago

      That's fine for personal use but professionally the main criterion is how widely the tool is used to solve business problems for paying customers.

  • koffiezet 5 years ago

    I only ever tried out a rails tutorial once, and coming from a C/C++ background, but having used with many languages, too many things felt like magic back then, but no further experience with the language itself, so can’t really judge it.

    However, now I’m on the operational side of things, and there are 2 types of applications I avoid to deploy/maintain, mainly because of their runtime: Java and Ruby apps. It’s very likely the Ruby runtime has improved, but we actually set up a haproxy with multiple instances of the same ruby app, which we just restarted every 2 hours, just to keep it running properly. Upgrading ruby back-then was a mess, and could break a lot of things. I can’t comment on the language itself, but the runtime left a very bad impression. I since then (4/5 years ago or so) have successfully avoided ruby, so it’s possible things have improved, but first impressions last...

    • Glyptodon 5 years ago

      I wouldn't call Ruby a high performance language, but your experience seems weird. Even four or five years ago I would consider Ruby one of the most painless languages for dealing with upgrades and new versions of things: install ruby with a version management tool, install your app from gemfile, run your tests, good to go. I regard it at one of the first languages to have effective tools for dealing with versioning and upgrades. I still find it easier to deal with than Python by a solid amount.

    • throwaway189262 5 years ago

      I hate deploying Ruby and Python because all the system packages they tend to use. Getting something working typically involves a bunch of crash/install cycles and some manual compilation and package downgrading.

      Go is easiest if we're talking about pre compiled binaries. If you include builds, dependency hell is real.

      C#, JS, and Java have been easy for me. Install JVM/CLR/Node and run one command. Old school Java with EE servers and Tomcat and such was a nightmare but everything I've done recently is self hosting

    • weaksauce 5 years ago

      the magic in rails is not really magic once you get used to the fact that all those magic incantations are just method calls inside the class. every class in ruby is just a series of method calls. you can write a class that, when it's read from the file and interpreted will just print something...

      class Foo

        puts "bar"
      
      end

      will just print `bar` when it's parsed.

      so something like has_many :baz are just the method call `has_many(:baz)` defined by active record. that creates a few functions using meta-programming. the other thing that ruby uses a lot of are blocks which are just anonymous functions. `do |a,b,c| puts a; end` just a function passed to the method that can be invoked by the function. I think those things are the ones that trip people up the most with when learning.

    • theonemind 5 years ago

      Reminds me of http://harmful.cat-v.org/software/ruby/rails/is-a-ghetto . "The main Rails application that DHH created required restarting ~400 times/day. That’s a production application that can’t stay up for more than 4 minutes on average."

      Not that Ruby = rails

      • Xylakant 5 years ago

        And yet, Basecamp is a successful company. So that tell us that crashing 400 times a day is not a problem in itself.

Justsignedup 5 years ago

Reactor model. Nice. Very nice. So real ruby multithreading at last.

Okay time to upgrade to latest rails and wait for the multithreaded rails release. :P

  • sosodev 5 years ago

    I suspect it will be quite a while before we see Ractor being used in Rails. Ractor is very strict about data isolation to prevent race conditions and existing code will need significant refactoring.

  • joelbluminator 5 years ago

    I don't understand what you mean by "real multithreading". What I understand from Ractor is that it makes it safer to write concurrent code (e.g there are constructs that keep you from mutating shared data). But there is still a global VM lock, or is that gone in Ractor?

    • lucraft 5 years ago

      I believe the VM lock is now per-ractor, so no longer global no. Then there are constraints on what can be shared between ractors to ensure safety.

  • dorianmariefr 5 years ago

    puma, the default webserver when using rails, is most-likely what would be using ractors

    • sosodev 5 years ago

      Here's schneems, a Puma maintainer, talking about Ractor, Rails, and Puma https://old.reddit.com/r/ruby/comments/ivasiq/we_made_puma_f...

      • jacobvosmaer 5 years ago

        >The biggest issue with ractor support as it stands today would really be getting ALL the libraries any given app uses to support the ractor design.

        I wonder if this will create a chicken-egg situation. Without significant Ractor adoption it will be hard to get libraries to adapt. Without essential pieces like Puma supporting (and benefiting from) Ractor there is less reason to for apps to use Ractor.

        I am reminded of the difficulties faced by Rubinius, which if I understand correctly, was hampered by too many MRI-compatible libraries not working to get people to switch.

        • sosodev 5 years ago

          I imagine getting wide support for Ractor will be easier than Rubinius and other async Ruby attempts since it’s actually part of the core language.

jasonhansel 5 years ago

Question: will the nonblocking scheduler start to make Ruby concurrency competitive with e.g. Node.js and Go? Currently Ruby mostly uses heavyweight threading mechanisms that cause trouble for I/O-bound microservices.

  • sosodev 5 years ago

    In theory the scheduler should be similar to NodeJS and Ractor should be similar to Go if they’re both applied correctly.

    • nesarkvechnep 5 years ago

      Isn't Ractor based on the Actor model and not CSP?

      • sosodev 5 years ago

        Ractor is "actor-like" and looks a bit like a mix of both Elixir/Erlang and Go.

        • dmix 5 years ago

          Indeed, anyone who has used actors IRL projects it goes well beyond just isolation and message passing. That’s just the foundation which higher abstractions are built, which is why it’s still comparable to Go/CSP at this level.

    • cutler 5 years ago

      Really? Can you point me to details supporting this?

  • andoriyu 5 years ago

    Well, ruby was able to be concurrent for a while now. It has lightweight cooperative threads, it has reactor loops. The problem was/is/will be - lack of gems that support either of them.

    EventMachine was a nightmare to work on and to work with, but with fibers it and some wrappers you could write some neat code. Most library were making a lot of bad assumptions - "there is a GIL and i'm running on a full thread and also wtf are threads in general, never heard of it?"

    Almost no one in ruby world thought about writing a better code to make application faster, it was always about either finding a better gem or adding more application servers. Here is the closest ruby has been towards concurrency https://github.com/igrigorik/em-synchrony guess why it never took off.

    Ruby 3.0 is a first step towards having libraries being aware that they are in on fiber and not thread.

  • maxpert 5 years ago

    In theory yes; but if there is something native that uses blocking API then your thread will be still blocked.

  • ioquatix 5 years ago

    Yes.

gorgoiler 5 years ago

It feels like RBS is for library writers, so that they can ship type information to help the consumers of their library. It’s not really aimed at the consumers themselves — the long tail of casual Ruby hackers like me.

If RBS was for end users, adding types inline with the source code would make more sense compared to the RBS approach: keeping the source file and typedef file in sync.

That might actually be a pretty smart move. At first it seemed inconvenient to have to maintain a separate file for the type information, but maybe this focus on type-checking being made easy for the 90% of us who hack scripts is a much smarter one.

  • schneems 5 years ago

    I don’t think anyone expects you to maintain two files. The idea is that RBS is an interface that is tooling agnostic. The idea is to have tooling (sorbet, etc.) generate those files for you.

crb002 5 years ago

I wish I had kept maintaining my port of Ruby to the IBM BLue Gene/L, "Blue Ruby". It scaled to millions of cores with MPI. Had distributed versions of familiar Ruby data types. There was no fork() - restriction of the BGL kernel not supporting it - only green threads - making parallel operations truly parallel with independent Ruby VMs and passing code to data instead of data to code.

Jarred 5 years ago

Does message passing mean it copies objects you send between threads / fibers, rather than sharing memory?

JavaScript has a similar pattern with Workers, and it makes concurrency for hot code impractical. Serializing/deserializing objects is a lot slower than just not doing that. In JavaScript’s case, you can also use SharedArrayBuffer, but Safari hasn’t re-enabled it.

  • kevincox 5 years ago

    IIUC Yes. Although there are some cases where it can share immutable objects or pass ownership.

    However you can always just open a shared memory region and write bytes back and forth. You don't get ruby types but if you are worried about performance that probably isn't much of a concern.

wbharding 5 years ago

It looks like the link they provide for comparing the source of 3.0 and 2.7 is busted on Github, but you can get a sense for the scope of this on GitClear's Open Repos https://www.gitclear.com/open_repos/ruby/ruby/releases. Looks like about 4x more repo evolution has gone into this version than previous.

See also: list of the biggest tickets tackled in 3.0: https://www.gitclear.com/open_repos/ruby/ruby/release/pendin...

riffraff 5 years ago

the link to the NEWS file is broken, it should be this

https://github.com/ruby/ruby/blob/v3_0_0_preview1/NEWS.md

desireco42 5 years ago

There were times where I would not be able to sleep when such a release was done :). It isn't as much lately, but still, fantastic work by fantastic team. Congratulations!

There are some seriously good stuff there.

juliend2 5 years ago

Happy to see developments on the pattern matching feature[0].

[0] https://bugs.ruby-lang.org/issues/16828

  • leetrout 5 years ago

    How do you intend to use this feature? I struggling to see the value.

    • jimbokun 5 years ago

      Seems like you could use it to turn hashes and arrays into poor man’s sum/product types.

sickcodebruh 5 years ago

Didn’t see it linked in the preview announcement, here’s the RBS syntax guide: https://github.com/ruby/rbs/blob/master/docs/syntax.md

Glanced at it from my phone but it looks good! I’m looking forward to seeing it in RubyMine. Still sad that we can’t write these in .rb files but I wonder if the plan is to go the other way, eventually permit typed code in .rbs?

Does anyone know what the story will be with third-party definitions? Are we headed towards a DefinitelyTyped style repository for Ruby?

  • sosodev 5 years ago

    It seems like the intent is for RBS to be auto generated from other tooling. Sorbet for example lets you write inline type definitions and is planned to fully integrate with RBS.

    The other good thing about RBS being in separate files is it can be integrated into a library without breaking compatibility with older Ruby versions.

aryik 5 years ago

Great stuff! Does anyone who’s been in the Ruby ecosystem longer than me have a prediction for when Rails will support Ruby 3?

bilekas 5 years ago

Am I alone in saying; for some damn reason, I don't like Ruby.. I appreciate what it can do, and indeed what it does.. I just feel like I slipped in between that moment to appreciate it more. I will go and spend some time to learn it more but out of a novelty aspect.. And that makes me feel bad.

  • Glyptodon 5 years ago

    I find it more productive, intuitive, and painless than the major scripting languages (PHP, JS, Python...), but it's definitely a bit different and less popular (given Python and JS are insanely popular).

  • joelbluminator 5 years ago

    No you're not alone, it's (surprisingly, to me) one of the more controversial languages. I love it. Lot's of people don't. These things are subjective, we don't all have the exact same brains and life experiences, us humans appreciate different things and that's fine.

jakearmitage 5 years ago

Endless Ruby is the best Ruby.

aitchnyu 5 years ago

Not a Rubyist. Would Ractor allow one process to use up all CPUs while avoiding copying objects? Can I build shareable objects with immutable lists and maps right now?

  • sosodev 5 years ago

    Yes, Ractor allows you to share fully immutable objects. So you can freeze an array or hash and share it as long as it doesn’t contain any references to mutable objects.

phplovesong 5 years ago

Look like a great release! Have not used Ruby in years, but i recon the Ractor and Scheduler brings some nice perf improvements.

pw 5 years ago

Wondering how RBS will compete/compare to Sorbet, which seems like a better solution.

nanna 5 years ago

Anyone got suggestions for resources to learn Ruby and Rails in 2020?

justinzollars 5 years ago

Rightward assignment looks gross.

sarfraaz 5 years ago

I don't know why am I writing this, but..

monadic2 5 years ago

Ruby is a really cool language but I'm dying for an update where features are removed.

  • choward 5 years ago

    Then Ruby isn't your language. There are a million ways to do everything by design. It's so you can make your code look pretty (or as they like to say "expressive") for whatever you interpretation of that means. It's one of the things that made me stop using it for most things.

  • riffraff 5 years ago

    $SAFE was removed in this one :)

  • Lordarminius 5 years ago

    The language is just becoming needlessly (?) complex. I'll stick to writing my code in --version 2.7 for the foreseeable future

zelly 5 years ago

So now there are basically no dynamically typed languages left. There's Scheme, JavaScript, what else? All languages nowadays are converging to TypeScript/Rust. It's kind of sad.

  • theonemind 5 years ago

    Static typing seems like the underdog outside of Java EE/big enterprise stuff.

    A matter of perspective, I suppose. You seem to like dynamic typing so static typing seems ubiquitous and inescapable. I find dynamic typing completely infuriating over 100 lines or so, and dynamic typing seems inescapable.

    Others have pointed out the big dynamically typed languages, so I won't rehash, but suffice it to say, there basically are some dynamically typed languages left.

  • smabie 5 years ago

    Julia, Python, Racket, Ruby, Common Lisp, Erlang, Clojure, etc...

    But in my opinion, dynamic typing is a terrible idea for production code.

    • zelly 5 years ago

      All of those offer static type checking. Python and Ruby's don't necessarily change how the code is compiled, but it might in the future. Common Lisp declare/declaim/proclaim changes the way the code is compiled; it's not just a linter. Clojure is definitely not dynamically typed, unless you consider Java to be dynamically typed.

      Also dynamic typing is more productive (for application code, not talking bootloaders here). It's a measurable fact and apparent to anyone who has written code long enough. Writing out types for everything is mostly pointless clerical work which should be able to be done by computers.

  • volkk 5 years ago

    what do you mean? you can certainly use vanilla javascript if you really want, same with ruby. its not like types are forced down your throat

    • jasonpeacock 5 years ago

      Ditto for Python, you can not use the type hints/don't run MyPy.

      OTOH, by skipping typing you lose a lot of guardrails and won't discover bugs until runtime.

  • loktarogar 5 years ago

    RBS is optional.

    • zelly 5 years ago

      It won't be optional in Ruby 4, most likely.

      • Daishiman 5 years ago

        Why would you think that? There's no evidence that dynamic typing is going away Type hints are optional precisely because they're not convenient for many cases, and the add-on type systems cannot fully express the capabilities of the language.

      • grumple 5 years ago

        Seems unlikely. Ruby is all about options.

      • joelbluminator 5 years ago

        Yeah, I second the opinion that this remains optional. Ruby won't become a java-wannabe , that's a fight it cannot and would not want to win. Ruby is dynamic.

      • nindalf 5 years ago

        I wish I could predict the future with as much certainty as you.

  • stevula 5 years ago

    Python is pretty popular

  • mattgreenrocks 5 years ago

    I hear x86 is dynamically typed

  • schwartzworld 5 years ago

    Is JavaScript dead? what the fuck is my browser running?

hexbinencoded 5 years ago

I left Ruby because the performance and security weren't improving and the community was slowly dying. I delved into Go before that got flooded with newbs, then looked at Crystal and Pony, before settling on Rust and Haskell for most things.

  • shawxe 5 years ago

    I see comments like this often and I find them deeply confusing. To me, it seems like most of the different programming/scripting languages you've listed excel at completely different things. I would be curious to hear what type of work you're doing where all of these languages have been, in some form or another, appropriate.

  • nurettin 5 years ago

    How do you choose all this? I haven't been able to make a single decision for what language to use at work for the past 15 years. I thought wouldn't touch C#, ruby, delphi, kotlin and python but it all happened because someone was paying.

    • vivab0rg 5 years ago

      > I haven't been able to make a single decision for what language to use at work for the past 15 years.

      Hello PHP.

  • joelbluminator 5 years ago

    In 5 years I bet you'd "settle" into some other new shiny language with "better" everything. There'll be a more right tool for the job. Nothing wrong with that mentality, I just prefer to settle with my tool of choice and call it a career.

stevebmark 5 years ago

I really wish Ruby would grow up and deprecate method_missing

  • chrisseaton 5 years ago

    > I really wish Ruby would grow up and deprecate method_missing

    method_missing is a deliberate and principled part of a message-passing approach to object orientated programming that gives you powerful options for composition and delegation.

    You can say you don't prefer this style of programming, but it's not well-informed to say it's down to immaturity or ignorance of alternatives on their part.

    • choward 5 years ago

      What do you mean by "powerful". Meaning you can type less code. You can still do delegation by writing it out yourself. Or you can also use the Delegator or Forwardable classes to save some typing. I'm not sure what meta programming they use under the hood. Probably define_method or method_missing.

      Also, people always forget to throw NotImplemented errors which can lead to some fun to track down bugs if you make a typo sending a message. Which I guess is why you pretty much have to write tests for everything in ruby. This kind of stuff would be caught by a compiler in other languages.

      Disclaimer: I don't buy into the idea of "message passing" or a lot of OOP. They're the microservices of programming languages.

      • chrisseaton 5 years ago

        > I don't buy into the idea of "message passing" or a lot of OOP. They're the microservices of programming languages.

        Then this probably was never the right language for you in the first place.

        But let's not say that people with different opinions about language design to you own need to 'grow up'.

  • nurettin 5 years ago

    Metaprogramming is an important part of ruby, so method_missing stays.

  • samgranieri 5 years ago

    Why? method_missing is one of the fun features of the language

  • whitepoplar 5 years ago

    What's wrong with it?

    • sigzero 5 years ago

      Nothing. There is nothing wrong with it at all except he "doesn't like" it.

cutler 5 years ago

Much as I would love to believe Ruby 3.0 delivers some kind of speed bump my simple test of doing what Ruby supposedly does best - parsing a log file with a regex - shows Ruby 16% slower than the Python equivalent.

  Ruby
  puts IO.foreach('logs1.txt').grep /\b\w{15}\b/

  Python
  from re import compile

  with open('logs1.txt', 'r') as fh:
      regex = compile(r'\b\w{15}\b')
      for line in fh:
          if regex.search(line): print(line, end='')
On my MacBook Pro (2013) running Catalina Ruby averaged 1.49 secs and Python 1.27 secs. The file `logs1.txt` is a 20Mb Apache log file. Pre-compilation with:

   reg = Regex.compile /\b\w{15}\b/
   puts IO.foreach('logs1.txt').grep reg
... slowed Ruby down to 1.57 secs.

Using --jit didn't change Ruby's overall time but considering it adds 700ms to Ruby's startup time execution time was faster.

  • karmakaze 5 years ago

    The programs aren't doing the same things. The Ruby one seems to buffer the matches into a huge string then print. Don't know how different it would be but better to compare apples.

    • riffraff 5 years ago

      Probably the equivalent thing to test would be

            regexp = /\b\w{15}\b/
            IO.foreach('logs1.txt') do |line|
              puts line if regexp.match?(line)
            end
      
      I imagine this will in both cases mostly be testing the computer's IO.

      Regexp.compile doesn't do anything substantially different from Regexp.new or a literal (i.e. it doesn't optimize the regular expression or something) so I think the difference is just random fluctuations.

    • cutler 5 years ago

      IO.foreach without a block returns an enumerator.

      • cutler 5 years ago

        You may be right. This version:

            IO.foreach('logs1.txt') {|x| puts x if /\b\w{15}\b/.match? x }
        
        ... runs in 1.3 secs, ie. same time as Python. Still, I exepcted Ruby 3x3 to beat standard Python.
  • TylerE 5 years ago

    That's not really surprising since regex in most languages is PCRE and not really indicative of actual interpreter performance.

    • cutler 5 years ago

      If that's the case why is Ruby slower?

      • byroot 5 years ago

        Your Ruby snippet is slower for two reasons:

          - IO.foreach is lazy, but then you call `Array#grep` on it which allocate a huge Array
          - `grep` populate the "last_match" object, `String#match?` is much faster.
        
        Try rifraf's snippet: https://news.ycombinator.com/item?id=24597067, it should be as fast as Python.
      • TylerE 5 years ago

        Because what you’re really measuring is something like how well the block size the interpreter uses for IO matches the underlying os/hardware

        • cutler 5 years ago

          If they are both doing similar things and one is faster that's still significant. So Python's i/o is faster than Ruby's.

  • Ecco 5 years ago

    But it’s a super easy to read one-liner in Ruby!

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection