7 ms·
> the language designs are so similar that I could just as well imagine a world where Python is the web development lingua franca, and Ruby has all the machine
by dialamac 6y ago
> the language designs are so similar that I could just as well imagine a world where Python is the web development lingua franca, and Ruby has all the machine learning libraries.
Well aside from the startling implication that Ruby is a web development “lingua Franca.”...the latter statement is reasonable, as it turns out language design isn’t actually that important here. But the former is pretty far off the mark. I mean, Ruby doesn’t even have first class functions and is very strongly smalltalkish in its OO purism, it has mutable strings a-la Perl. The async story is obviously quite different. Python has a much more complicated interpreter, which has contributed to it being more difficult to get even simple optimizations that are done in Ruby. They’re really only similar in the most superficial sense... in the same way that all current dynamic interpreted languages will do certain things similarly.
- viraptor 6y ago> it has mutable strings a-la Perl Yes, but they're not popular these days. Ruby 3 almost defaulted to frozen-strings by default (I wish it had) and a lot of the ecosystem moved to that style resulting in some nice memory saving. Rails enforces it on its code for example: https://github.com/rails/rails/blob/0f09dfca363410f51f6f60787a0e497ee66cdd13/.rubocop.yml#L143 https://github.com/rails/rails/blob/0f09dfca363410f51f6f6078...
- mbell 6y agoYou are talking about string _literals_, there is no motion nor interest I'm aware of in making all strings immutable in Ruby, thankfully.
- capableweb 6y agoWhile I agree with most of your comment, "Ruby doesn’t even have first class functions" sticks out. Not because it's not true, but because it doesn't really matter as Procs are first class in Ruby and can be used in all the same ways, so it doesn't really affect things except introducing something you might need to learn coming from JS or any other language where functions are first class.
- jablan 6y ago>it doesn't really matter This way can be argued for almost every language, as they almost all allow some form of passing a piece of code to a function. The difference is what matters - whether that's elegant enough to be widely used or not. Ruby is, frankly, somewhere in between.
- deleted 6y ago[deleted]
- Toutouxc 6y ago> Ruby doesn’t even have first class functions I'm genuinely curious what is it that you miss in Ruby regarding functions (my Ruby is pretty OOPish and I try to avoid functional magic). AFAIK you can do stuff like currying/partial application with lambdas and you can get a hold of any method by name and use it as a lambda, pass it to other functions, use it as a block etc. Is there something we're missing compared to, say, JavaScript?
- pmontra 6y agoYou can pass a function as argument using its name in Python and then call it. You must pass it as a symbol in Ruby and then send to it. def f(x): return x def g(fn, x): return fn(x) g(f, 1)
- inopinatus 6y agoRuby can definitely pass around several varieties of closure and related constructs, including procs, blocks, lambdas, bindings, continuations, fibers, and both bound and unbound methods. Whether we should is another matter, and the syntax and idioms certainly lean towards preferring a symbolic late binding, but the language is multi-paradigm, and one may write purely functional Ruby if desired, immutable values and all.
- Toutouxc 6y agoNo, passing a symbol and sending is a different mechanism. The send method is basically the same thing as calling a method by name, as in "obj.foo" == "obj.send(:foo)". If you only pass a symbol into your "caller" method, the symbol goes through the normal lookup: does the receiving object respond to this? If yes, then that implementation (at that exact moment) is called, if not, you get a method_missing. You're right that that's not how you do first-class functions in ruby. Your example in ruby would be: def get_and_call(fn, x) fn.call(x) end def upcasinator_method(str) str.upcase end upcasinator_lambda = lambda {|str| str.upcase} get_and_call(upcasinator_lambda, 'foobar') => "FOOBAR" get_and_call(method(:upcasinator_method), 'foobar') => "FOOBAR" As you can see there are two ways to do that -- either you create a Proc (a lambda if you care about arity), which is the first class function in Ruby, and you call that, or you define a method (but that's a method, an OOP concept, a procedure that implicitly operates on an object), you get a hold of it using the "method" method and then you call it.
- sedeki 6y agoWait, Ruby doesn't have first class functions? I'm pretty sure it does and that it is full-fledged, compared to Python's intentionally restricted `lambda` syntax.
- capableweb 6y agoNope! You can't pass functions, return them from other methods and so on, so it's not first class. What you do have in Ruby is Proc, that can be used kind of like first class functions, so you don't really miss out on much.
- syspec 6y agoAh, so it's the same then
- feanaro 6y agoNot really the same since lambda in Python is just a syntactic variant that is restricted. A function defined using `def` can be passed around without restrictions, which you simply cannot do in Ruby.
- zwp 6y agoMaybe I misunderstand your use of the word "function" here, but in addition to Proc/lambda you can certainly reference a method, pass that around, return it, call it? See: * https://ruby-doc.org/core-2.7.1/Method.html * https://ruby-doc.org/core-2.7.1/Object.html#method-i-method $ irb 2.3.3 :001 > p = Kernel.method(:puts) => #<Method: Kernel.puts> 2.3.3 :002 > p.call "Hello" Hello => nil 2.3.3 :003 > def run_a_method(meth, *args) 2.3.3 :004?> meth.call(*args) 2.3.3 :005?> end => :run_a_method 2.3.3 :006 > run_a_method(p, "Hi!") Hi! => nil 2.3.3 :007 > ps. this also works with the "to_proc" operator (&) so you can do this: [1, 2, 3].each(&Kernel.method(:puts)) (but I wouldn't necessarily recommend this since it's not very readable, at least to my eyes).
- inopinatus 6y agonew crew dialamac gotta be dissin / says Ruby first class functions are missin / tries it on in da y combinator / but y = -> f { -> g { g[g] } [ -> g { f[-> v { g[g][v] }] } ] } / see ya later.
- dialamac 6y agoI’m amused that a number in this thread saw these observations as a “diss”... that’s more on you then me. I didn’t pass any value judgement on these differences, merely that they exist and demonstrate some fundamental differences in the history of these languages. While Ruby lambdas are essentially first class anonymous functions they were added late in the language and they are distinct from methods that predate them. You can’t just drop them in seamlessly where a method is used. The point stands that while both Ruby and python have accreted more stuff as time wears on, their initial design principles were starkly dissimilar.
- inopinatus 6y agoYo bro dialamac / Caught in a falsehood / Tryin' to dial it back / Feels misunderstood / Sez lambda came late / But changelog don't lie / Since v0.8 / Ruby so fly. Or, in prose form: I don't see anyone disagreeing that Ruby & Python are dissimilar both in principle and in practice, but "Ruby doesn't even have first-class functions" was most unreservedly an epic howler, and once played, folks were inevitably gonna have some fun passing that football around, and despite most of the changelog from 1995 being in Japanese there are nevertheless references to lambdas that early on, although the more concise "stabby" syntax didn't rear up until ca.2008.
- dialamac 6y ago[See screenshot]
- inopinatus 6y ago> "Functions in Ruby are methods" RECORD SCRATCH. THE ROOM FALLS SILENT. NARRATOR: A common assumption, but no. Equating object methods to functions is a furphy. The argument along the lines of: "Ruby's object methods are Ruby's functions, but you can't pass them around, ergo they're not functions" is using the term "function" in two different ways, but assuming they're the same; this is not an argument based on substance, but upon mislabelling. The conclusion is bogus because the premise is bogus. It may arise from a category error, assuming that the thing depends intrinsically upon the literal representation of the thing, or (worse) the common name of the thing, but this is a) wrong anyway, and b) loses coherence entirely in a language in which function literals can be conjured and lexically rebound at runtime. In actuality, Ruby's lambdas are functions, and first-class, by the only definition with substance: they are closures capable of higher-order expression, taking functions as parameters when invoked, and returning functions as results. Which is why saying "it don't have them" on a forum named after a fixed-point combinator is to invite: a) ridicule, and b) lambda calculus expressions in rap battle form. CROWD: Yeah! MUSIC STARTS / GLITTERBALL CLOSEUP