5 ms·
> In Crystal, as in Ruby, everything is an object. [...] When you write Crystal code, most of the time, you write classes. Why, God, why?! Really, OOP is a gre
by nnq 9y ago
> In Crystal, as in Ruby, everything is an object. [...] When you write Crystal code, most of the time, you write classes.
Why, God, why?! Really, OOP is a great way of structuring lots of types of code (not all!). But I don't think it really helps anyone to treat everything as an object. Some things are not objects they just are whatever they are. A function is just that, a function. If I have to call a `.call` method on a "function" as in ruby, then that's simply not a function anymore. And... it's not an object either semantically, because objects are about things that can receive and send multiple messages and sometimes encapsulate state... and that's not how anyone thinks about functions!
By making everything be an object, you actually f up the concept of "object" itself...
I like Ruby's elegance, but every time I see the "OOP at the core" part, I suddenly get more love for Python and Javascript for at least getting this right.
- pjmlp 9y agoPython is also OOP at the core, in case you have not been paying attention. Likewise Prototype-based programming is OOP.
- jhbadger 9y agoPython kind of cheats, though. Not everything is an object -- most low level things like arrays and numbers aren't. Ruby is from the Smalltalk tradition where everything literally is an object -- and I say that as a good thing. Even the "functions" that you can define are really methods of the Object class -- it just happens to be the case that Object.foo(x) can be abbreviated as foo(x).
- pjmlp 9y agoFor the regular user they behave like objects > import builtins > builtins.int => <class 'future.types.newint.newint'> class myint(int): pass
- joaodlf 9y agoI have never used Crystal before, but I don't understand how you can be against "everything is an object" and then say Python and Javascript are different... Pretty much everything in Python and JS is an object... So really, what does fundamentally differ?
- Shoothe 9y ago> Pretty much everything in (...) JS is an object Except primitives that are not objects but (some) can be autoboxed to behave like objects. A riddle: var a = 2; a.b = 3; console.log(a.b);
- nnq 9y ago> So really, what does fundamentally differ? Sure, one can argue that nothing ever fundamentally differs because all languages are Turing complete, but... When I decide to use functions in a language that has objects, 99% of the time it is implied that a function either 1. holds no state, aka "referential transparency" 2. if it manages external state, it does it by modifying one of its arguments (usually the first one and in a very obvious way) This allows nice mixing of functional and OOP! ("mixing" by keeping things separate, paradoxically :P...) I know that if I see a piece of code with a dance of functions that take in and/or generate functions etc., that's a "functional zone" of a program and those function obviously don't have state. When the only way of passing functions to functions and returning them is basically the same thing as passing and returning objects, you'll always be lost when reading someone else code and have to ask yourself at every step: "is that thing that receive the `.call` message maybe also holding some state". Or you'll always be unable to just assume that a function is referentially transparent, because "it's OOP, object aren't RT, dooh". This places a huge mental burden when reading/understanding other people's code! (And yes, in Python or JS you can also treat functions like objects and even attach fields and methods to them, BUT there is no not-extremely-awkward or obvious way to mutate those from code inside the function. Referring to the function by name makes it obvious. Using stuff like `arguments.caller` is awkward and widely accepted as bad practice. Only static variables in C++ allow such "muddying the semantic waters" practice easily, but they are also bad practice and easy to grep for.)
- RX14 9y agoThis actually isn't really the case in Crystal, or at least not as much as in Ruby. We allow you to create a proc (closure) from an existing method/function but methods themselves are just methods. Classes have metaclasses though, which are fairly useful for some neat reflection-like behaviour. None of this really matters, even if functions were objects, then as long as that fact gets out of your way just don't take advantage of that.
- coldtea 9y ago>And... it's not an object either semantically, because objects are about things that can receive and send multiple messages and sometimes encapsulate state... and that's not how anyone thinks about functions! Well, functions can "sometimes encapsulate state" (closures), and can send and receive multiple messages (.call, .toString, etc depending on the language). >I like Ruby's elegance, but every time I see the "OOP at the core" part, I suddenly get more love for Python and Javascript for at least getting this right. Almost everything is an object in Javascript as well (just in a botched way). The difference is in how inheritance happens, not in having objects or not. Ditto for Python.
- camus2 9y ago> Why, God, why? Afaik, both Ruby and Crystal allows you to write dumb functions and procedures, if you love C style structured programming. def plus_one(x) x + 1 end So perhaps you should calm down a bit.
- interfixus 9y ago> dumb functions and procedures Perhaps you should.
- goatlover 9y agoFunctions are objects in Python and JS, btw. And primitives can be treated as objects. They are wrapped by prototypes in JS, and belong to type classes in Python. Ruby's elegance stems from being able to treat everything as an object sending messages to other objects, like Smalltalk. Some languages promote a certain style of programming. You might as well complain that Haskell is functional, and Lisp is homoiconic. Howevver, Ruby & Crystal still let you define functions and write statements as if they were procedural.
- nnq 9y ago> and write statements as if they were procedural my issue is not with writing procedural code, it's with the way functional parts of a program "mush" into "OOP-statey" with no obviousness of boundary. It feels kinda "dirty".
- deleted 9y ago[deleted]
- dragonwriter 9y ago> I like Ruby's elegance, but every time I see the "OOP at the core" part, I suddenly get more love for Python Python does the same thing; functions are objects. Ruby needs a call to .call or the equivalent .() syntax because of optional parens, not because of pervasive OOP.,