News for hackers. Stuff that matters.
Re:Ruby 3.4.0 by oezi on Wednesday December 25, 2024 @04:48AM (#42507938)
Ruby has the nicest object-oriented design (everything is an object) outside of smalltalk (IMHO).

In contrast to the mess that is Python. For instance, in Ruby it is natural that each or map are methods of Array or Hash rather than global functions which receive an Array or Hash argument.

This goes as far as having the not operator '!' as a method on booleans:

false.! == true

Once you have understood it, it is a very beautiful language.

Re:Ruby 3.4.0 by cyberpunk on Wednesday December 25, 2024 @05:07AM (#42507995)
It's very powerful though which is a bit terrifying. You can literally monkey patch Object at runtime and add methods to every single instantiated object! (I believe this is how rspec works..)

Awesome, but with great power come great responsibility ;)

Re:Ruby 3.4.0 by tuyiown on Wednesday December 25, 2024 @05:26AM (#42508057)
Actually, learning ruby is great way to see the light and stop trying to be creative when writing code.

You end up feeling and steered to the the right idiomatic way of doing things is the satisfying way.

Re:Ruby 3.4.0 by codesnik on Wednesday December 25, 2024 @07:37AM (#42508514)
RSpec moved from that quite some time ago. Monkey patching nowadays is usually frowned upon, even refinements, which could simulate monkey patching in a limited scope, are rarely used.
Re:Ruby 3.4.0 by cyberpunk on Wednesday December 25, 2024 @02:18PM (#42510558)
Oh I'm extremely out of date, I was into ruby back when Why's guide was a thing. Maybe I'll revisit it someday if I ever get bored of go paying the rent.
Re:Ruby 3.4.0 by psychoslave on Wednesday December 25, 2024 @10:49AM (#42509337)
Yes, but it is not fully OO. Something like `if.class` generates an error, as opposed to returning some type such as "Syncategoreme".

That might looks really anecdotal, but on practice for example that's is probably the biggest obstacle to providing fully localized version of Ruby for example.

The second biggest challenge to do so would probably be the convention of using majuscule to mark a constant, which thus requires a bicameral writing system. That is rather ironic given that none of the three writing system of Japanese is bicameral (looks fair to exclude romaniji here). Though this can be somehow circumvented with tricks like

``` # Define a global method dynamically Object.send(:define_method, :lowercase_constant) do "This is a constant-like value" end

# Usage puts lowercase_constant ```

Re:Ruby 3.4.0 by int_19h on Wednesday December 25, 2024 @08:30PM (#42512505)
Everything is an object in Python, as well.

Stuff like map() is generic iteration, over any structure that exposes iteration. When it's a member function, it means that every collection has to implement map itself basically. When it's separate, the collections only need to provide the interface needed to iterate over it, and the generic map() will just use that.

Re:Ruby 3.4.0 by Maledictus on Thursday December 26, 2024 @06:46AM (#42514669)
Still looks much less beautiful. Python feels to me like it can't make up its mind.
Re:Ruby 3.4.0 by int_19h on Thursday December 26, 2024 @04:25PM (#42517942)
I'll take "properly generalized" over "looks beautiful" any time. At the end of the day, the purpose of the code is to do something, not to be pretty.

FWIW you can have both in this case; you just need to make dotted method calls syntactic sugar for global function invocations.

Re:Ruby 3.4.0 by rakoo on Thursday December 26, 2024 @06:10PM (#42518596)
And some will say the exact opposite: contrary to what would seem obvious, code is primarily meant to be read by humans, then written by humans. Because you'll spend way more time unfucking code than actually spitting it.
Re:Ruby 3.4.0 by lucasoshiro on Thursday December 26, 2024 @08:08AM (#42514956)
> over any structure that exposes iteration

Taking OOP more seriously, this kind of thing should be implemented through inheritance, interfaces, mixins, etc. Even though I've got used to it, Python has these inconsistencies that sometimes it wants to be more OOP, sometimes it wants to be more FP.

Ruby has chosen OOP as its size, and implements nicely those functional operations as methods (same for Kotlin, for example). That makes easy for composing them:

# Sum of the square of even elements of a list, in Ruby

my_list.filter{|x| x % 2 == 0}.map{|x| x * 2}.sum

Python could do something like that, but we quickly fall in a parentheses hell:

# The same code, in Python

sum(map(lambda x: x * 2, filter(lambda x: x % 2 == 0, my_list)))

Languages that have chosen the FP path more seriously implement function composition. They could do the same way as Python, but composition makes it more readable:

# The same code, in Haskell

sum . map (^ 2) . filter (\x -> x `mod` 2 == 0) $ my_list

PS: I know that I it would be better to use comprehensions in both Python and Haskell, but these are general examples

Re:Ruby 3.4.0 by int_19h on Thursday December 26, 2024 @04:23PM (#42517926)
Kotlin is still rather different though in that it still implements stuff like map and filter outside of specific collection classes. If you look at the definition of, say, List, there's no map & filter there, only iterator. Instead, map & filter are defined as extension functions that work on any Iterable.

So semantically it's actually closer to Python, with the only difference that, since Python doesn't have extension methods, it has to use global functions for this, while Kotlin lets you pretend that those methods are actually members. But this is pure syntactic sugar, not a semantic difference.