Live data from Hacker News

Ruby 2.7

ruby-lang.org

51–60 of 68 posts

Re: Ruby 2.7

#51
post #5

Earlier quoted context omitted.

what's the purpose of Either and Maybe in a dynamically typed language?

Pop an item from an array. What do you return when the array is empty? Solution: nil. Problem: How do you tell the difference between "the array was empty" and "the item you popped was nil"? Solution: have pop return a Maybe instead.

or solution: Null Object

or a whole value

or use an enumerator

or a collection decorator

All of which are simple solutions already available. No need to import every new paradigm hammer in the hope that everything is a nail.

Re: Ruby 2.7

#52
post #43

Earlier quoted context omitted.

The only modern problem with switching to C99 is Visual Studio on Windows. You have 2 sensible choices: 1) Use clang to build on Windows. 2) Use the subset of C99 which is implemented in Visual Studio (which also requires compiling as C++, which isn't that difficult to handle).

3) Use C++17 with minimal features. This gives you a lot of needed libraries built-in and it is better supported than C99 (due to Windows).

> Use C++17 with minimal features

To paraphrase JWZ, "now you have N+M problems"

Re: Ruby 2.7

#53
post #42

Earlier quoted context omitted.

Its an important change, but not huge, at least not yet: it's not yet integrated in the GC, which means you have to explicitly request it. And most of the fragmentation comes anyway from the allocations heap. That being said, I think this will improve in the coming releases.

What criteria should be monitored to request compaction in a long-running process? Is a timer sufficient (at what interval?) or are there other tools available in Ruby to make that decision?

It's likely to be most useful for anyone using a Unicorn-style process forking model in Ruby.

You call `GC.compact` in the parent right before forking off your child processes and because the memory in the children are copy-on-write (COW), it lets them share memory with their parent far longer than they normally would be able to.

Any change in a page (i.e. an object allocated or deallocated) causes it to be copied to a child process, and because previously pages were a mix of objects of all kinds of longevity and slots which may be empty or used, children tended to copy their parent's entire memory space very quickly. Running a GC and compact before forks improves the likelihood that shared pages are mostly full of still-in-use, longer-lived objects, and gives the COW strategy a fighting chance.

Re: Ruby 2.7

#54

Earlier quoted context omitted.

Pop an item from an array. What do you return when the array is empty? Solution: nil. Problem: How do you tell the difference between "the array was empty" and "the item you popped was nil"? Solution: have pop return a Maybe instead.

or allow returning multiple values. for example in CL searching for a thing returns two values the is-found and the value

Which is the same thing, but in an ad-hoc way, and leaves it open to the developer to check or not, and thus to crash.

Re: Ruby 2.7

#55
post #49
post #10

Earlier quoted context omitted.

Maybe I’ve just been bitten by the functional bug but I find they can communicate intent much better than scattering around null checks or catching exceptions (many of which require reading the source to understand what exceptions you might get). It’s great in large scale projects, which I think is where a dynamic language starts to show its warts.

Yeah I suppose my bigger beef is I just don't like dynamic languages. Perhaps it is in fact a good idea for them, but being someone primarily interested in types, it largely falls into the realm of "don't care."

Huh? Both Maybe / Optional and pattern matching is used in Haskell, Scala, and other typed languages... It's not about dynamic languages...

Re: Ruby 2.7

#56
post #10

Earlier quoted context omitted.

Maybe I’ve just been bitten by the functional bug but I find they can communicate intent much better than scattering around null checks or catching exceptions (many of which require reading the source to understand what exceptions you might get). It’s great in large scale projects, which I think is where a dynamic language starts to show its warts.

An alternative to scattering null checks around or using exceptions for control flow could be more thoughtfully designing your data/object model. No additional language constructs required!

That attitude is the source of billions of dollars in bugs...

Never manually do the work that the compiler / runtime could do.

You can design "more thoughtfully designing your data/object model" (in other regards) AND have the compiler make sure you're not doing null referencing for you (so that that's not your concern anymore) -- instead of manually and in an ad-hoc way per project implementing another menial responsibility into the design of your model.

Re: Ruby 2.7

#57
post #50

> Calling a private method with a literal self as the receiver is now allowed. Oof. Call me old fashioned, but I liked the consistency of not being able to call private methods with an explicit receiver. Oh well! The rest of this looks great, thanks Ruby team!

Funny thing: I always bring up how Ruby has private methods while Python doesn't, when toying around with colleagues about languages, etc. well there goes that I guess. Sidenote: I can't think of a use case where this is a good idea.

You've been able to use `send` to pierce the protected/private restriction forever, so this doesn't particularly change the nature of Ruby's method visibility rules. Now you can just use `self.foo` and it's the same as `self.send :foo`.

    class Foo
      def test
        priv             # works
        self.send(:priv) # works
        self.priv        # doesn't work under ruby 2.6-
        Foo.new.priv     # doesn't work
      end

      private

      def priv
        puts "ran private"
      end
    end
You shouldn't typically need to be using `self` at all, except when it's clarifying or disambiguating, so you shouldn't generally run into that issue. On occasion, though, you add a `self.` prefix to a method call and can break code that was otherwise working, because you've subjected your code to a scope protection that it wasn't subject to before.

Re: Ruby 2.7

#58
I'm most excited for Enumerable#tally for counting occurrences of elements.

From the example in the release:

  ["a", "b", "c", "b"].tally
  #=> {"a"=>1, "b"=>2, "c"=>1}
There's more about this change here (https://medium.com/@baweaver/ruby-2-7-enumerable-tally-a706a...). I probably do this a few times a week:

  list.each_with_object(Hash.new(0)) { |v, h| h[v.something] += 1 }

Re: Ruby 2.7

#59
post #57
post #50

Earlier quoted context omitted.

Funny thing: I always bring up how Ruby has private methods while Python doesn't, when toying around with colleagues about languages, etc. well there goes that I guess. Sidenote: I can't think of a use case where this is a good idea.

You've been able to use `send` to pierce the protected/private restriction forever, so this doesn't particularly change the nature of Ruby's method visibility rules. Now you can just use `self.foo` and it's the same as `self.send :foo`. class Foo def test priv # works self.send(:priv) # works self.priv # doesn't work under ruby 2.6- Foo.new.priv # doesn't work end private def priv puts "ran private" end end You shoul…

> You've been able to use `send` to pierce the protected/private restriction forever, so this doesn't particularly change the nature of Ruby's method visibility rules.

I wasn't aware, thanks for pointing that out.

Re: Ruby 2.7

#60

I'm most excited for Enumerable#tally for counting occurrences of elements. From the example in the release: ["a", "b", "c", "b"].tally #=> {"a"=>1, "b"=>2, "c"=>1} There's more about this change here ( https://medium.com/@baweaver/ruby-2-7-enumerable-tally-a706a... ). I probably do this a few times a week: list.each_with_object(Hash.new(0)) { |v, h| h[v.something] += 1 }

For Python developers: this exists as collections.Counter.
Post reply on HN