|
View:
New views
20 Messages
—
Rating Filter:
Alert me
|
| < Prev | 1 - 2 | Next > |
|
|
Not quite getting it.Hi,
I'm trying to get whats Ruby is all about. I've been doing .NET since beta so I'm kind of stuck in the static typed mindset. The parts that I do get: I love metaprogramming, I was able to make a port of my .NET AOP framework that took about 3 months to do in .NET in a week in Ruby (w/o ever touching ruby before.. ) I also understand that its nice with auto promotion of number types when they would overflow in other languages. What I don't get: How do you deal with ducktyping? How can anyone assume that just because a method exists that the semantics is the same? Brush.Draw( x , y ) vs Cowboy.Draw( direction, speed ) The same name and signature, not even close to the same semantic meaning. Doesnt this put an extra burden on the developer, that he has to know the exact intention of each and every method? Where in a language that supports ifaces you simply know that the methods associated with the interface have a certain meaning. The backside of dynamic typing. I got a mail from a newsgroup a few days ago with the title "we once overflowed a long at google" Ok ok, as I said, I get type promotion. But what if you assign a "Giraffe" to a property called "Orders" , isnt that just as bad or even worse than overflowing a number? If someone say "that should be caught in a unit test" , well so should the overflowed long (And Java and .NET can use big integers etc too if you need) And the thing that I have the hardest time with, how the heck do you learn to use someone elses framework / api ? in a typed language with decent intellisense I can see what types Im supposed to pass in and what I get back. One can often understand how to use an API by just looking at the intellisense. While I found myself browsing ruby docs back and forth just to see if the result of a method would be a string or an object etc. So can someone try to convert me or am I forever lost? :-P -- Posted via http://www.ruby-forum.com/. |
|
|
Re: Not quite getting it."in a typed language"
Before I get killed, I ment static typed.. -- Posted via http://www.ruby-forum.com/. |
|
|
Re: Not quite getting it.On May 16, 2008, at 1:45 PM, Roger Alsing wrote: > Doesnt this put an extra burden on the developer, that he has to know > the exact intention of each and every method? I kinda think that this is the basis of programming in any language... Here's the thing. I'm sure many people will try to convince you--this may end up being a thread that runs and runs. Ignore them. They'll never change your mind. The only thing that will is for you to try it. Try Ruby on larger programs. Try it for a month or too. And see what happens. If your programs die because brushes end up shooting people, then Ruby isn't the language for you. If instead you continue to enjoy a factor of 12 productivity improvement, maybe it is. Everyone's mileage will vary. Dave |
|
|
Re: Not quite getting it.On 5/16/08, Roger Alsing <roger.alsing@...> wrote:
> Hi, > I'm trying to get whats Ruby is all about. > I've been doing .NET since beta so I'm kind of stuck in the static typed > mindset. > > The parts that I do get: > > I love metaprogramming, I was able to make a port of my .NET AOP > framework that took about 3 months to do in .NET in a week in Ruby (w/o > ever touching ruby before.. ) > > I also understand that its nice with auto promotion of number types when > they would overflow in other languages. > > What I don't get: > > How do you deal with ducktyping? > How can anyone assume that just because a method exists that the > semantics is the same? > > Brush.Draw( x , y ) > vs > Cowboy.Draw( direction, speed ) > > The same name and signature, not even close to the same semantic > meaning. > > Doesnt this put an extra burden on the developer, that he has to know > the exact intention of each and every method? > Where in a language that supports ifaces you simply know that the > methods associated with the interface have a certain meaning. > > > The backside of dynamic typing. > I got a mail from a newsgroup a few days ago with the title "we once > overflowed a long at google" > > Ok ok, as I said, I get type promotion. > But what if you assign a "Giraffe" to a property called "Orders" , isnt > that just as bad or even worse than overflowing a number? > > If someone say "that should be caught in a unit test" , well so should > the overflowed long (And Java and .NET can use big integers etc too if > you need) > > And the thing that I have the hardest time with, how the heck do you > learn to use someone elses framework / api ? > > in a typed language with decent intellisense I can see what types Im > supposed to pass in and what I get back. > One can often understand how to use an API by just looking at the > intellisense. > > While I found myself browsing ruby docs back and forth just to see if > the result of a method would be a string or an object etc. > > > So can someone try to convert me or am I forever lost? :-P > > -- > Posted via http://www.ruby-forum.com/. > > Very oft brought up question, and valid in some points. int someInterestingMethod(int x, int y, float spock) { ... } What do those parameters mean? What do you pass into this function and what are you supposed to get out? Just having static types does not at all help with understanding what a function does. You need well named functions and arguments, with *documentation* on what the function does and what parameters are supposed to be. This is no different in a statically typed language vs dynamically typed language. The only thing a static typed language guarantees is that proper types were passed into the function. That's no guarantee that you're using the function correctly or that the function itself works at all. Only a comprehensive test suite will catch these kind of problems. Things like overflowing a float will happen to anyone in any language. So in short, all code should have: 1) documentation of what the method does, what the parameters are and what the return is. 2) properly named functions and parameters. neither of which has anything to do with the typing system of the language. There will be libraries who's maintainers don't document anything, leaving you to experiment and ask around. This is true for all programming and is something we just have to live with (and hopefully not propogate). Hope that helps you understand why dynamic vs static typing really isn't a issue. Jason |
|
|
Re: Not quite getting it.-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1 Roger Alsing wrote: | How do you deal with ducktyping? | How can anyone assume that just because a method exists that the | semantics is the same? Well, if it walks like a duck, and it talks like a duck, it probably is a duck. I.e. if a Class or variable reacts to certain methods, it probably is of the correct type. | Brush.Draw( x , y ) | vs | Cowboy.Draw( direction, speed ) | | The same name and signature, not even close to the same semantic | meaning. | | Doesnt this put an extra burden on the developer, that he has to know | the exact intention of each and every method? That's true of any language. .NET baffles *me*, for example. :P | Where in a language that supports ifaces you simply know that the | methods associated with the interface have a certain meaning. It's similar in Ruby (but not quite). Unlike more 'blue-collar' languages (not my term! And it is usually used in conjunction with Java, but it probably applies to .NET as well), Ruby doesn't try to protect you. It has some 'safety' measures, though. 'a string' + 2 Won't work, as the string is, well, a string, and the 2 is an integer. And you can't implicitly cast types in Ruby, for example. | The backside of dynamic typing. | I got a mail from a newsgroup a few days ago with the title "we once | overflowed a long at google" | | Ok ok, as I said, I get type promotion. | But what if you assign a "Giraffe" to a property called "Orders" , isnt | that just as bad or even worse than overflowing a number? Depends on the scenario, I guess, and what 'Orders' is supposed to do. If it is, for example, an array holding all items in a shopping cart, there is no issue. If 'Orders' is only supposed to contain objects of the class 'Fruit', you are of course in a bit of a pickle. However, the class 'Orders' is supposed to handle that. Note: I don't think that data structures like arrays or hashes can actually overflow. You can create them with arbitrary lengths (subject to limitations like available memory, obviously). Ruby's Array's aren't like (I think this is .NET syntax, but feel free to correct me, it's been a while) Array ary = Array[9];, where ary can hold only 10 members. | If someone say "that should be caught in a unit test" , well so should | the overflowed long (And Java and .NET can use big integers etc too if | you need) Well, this probably more an issue with the developer, than the language, from what I can see. | And the thing that I have the hardest time with, how the heck do you | learn to use someone elses framework / api ? How did you learn .NET? Same thing, really: Reading documentation, using tutorials, experimentation. | in a typed language with decent intellisense I can see what types Im | supposed to pass in and what I get back. | One can often understand how to use an API by just looking at the | intellisense. NetBeans, Eclipse, and Ruby in Steal (which is built upon visual Studio, but isn't free, but has actual IntelliSense(tm)) can do that for you. It hinges on the documentation provided by the gem / application you use to tell you what the method expects. | While I found myself browsing ruby docs back and forth just to see if | the result of a method would be a string or an object etc. Well, usually a Ruby object returns what you pass in. So, something that handles arrays, returns an array. I think. If that is what you mean. :) | So can someone try to convert me or am I forever lost? :-P Hey, doing something that took you 3 months in .NET in 1 week in a foreign language is a rather strong testimonial, isn't it? Though, as Dave Black suggested, you'll have to try for yourself. Work with Ruby for a while, and if you like it, you like it, and if you don't like it, then you don't like it. :) In my, admittedly limited experience in using statically typed language versus Ruby, I don't need the additional safety or benefits the static types provide. How ever, you mileage will vary. - -- Phillip Gawlowski Twitter: twitter.com/cynicalryan Blog: http://justarubyist.blogspot.com ~ - You know you've been hacking too long when... ...you're trying to get to sleep but can't because you don't know the right VMS logical--you keep typing SHOW LOGICAL *SLEEP* and never get anything but: SHOW-S-NOTRAN, no translation for logical name *SLEEP* -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.8 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAkgt3pwACgkQbtAgaoJTgL+kfQCfWxaHIIUz65IWBAnzfuJar9vH pk0AnjFjlIbpgW6F11fblZgMHmf0tOJg =8an1 -----END PGP SIGNATURE----- |
|
|
Re: Not quite getting it.-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1 On May 16, 2008, at 8:45 PM, Roger Alsing wrote: > How do you deal with ducktyping? > How can anyone assume that just because a method exists that the > semantics is the same? > > Brush.Draw( x , y ) > vs > Cowboy.Draw( direction, speed ) > > The same name and signature, not even close to the same semantic > meaning. Actually, how do you guarantee those semantics in a statically typed language? Consider this (pseudo-java, sorry ;) ): interface Drawable { abstract public void draw(int a, int b); } class Point implements Drawable { public void draw(int x, int y) { Canvas.drawPoint(x,y); } } class CarThief implements Drawable { public void draw(int x, int y) { Car c = steal(Cars.random()); c.drive_to(x,y); } } Both Classes implement Drawable but there is no way to check on two "Drawable" whether they share the same semantics. Regards Skade -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.8 (Darwin) iEYEARECAAYFAkgt67EACgkQJA/zY0IIRZZ1sACgmVHN1laF+Xqr72t887Pd+n3J TwwAniR9ESpQ0gwVGcOA5r4opjn1hLJ+ =GhYL -----END PGP SIGNATURE----- |
|
|
Re: Not quite getting it.Florian, your example is not a fair one; it illustrates an intentional
violation of the semantics, whereas Roger is referring to an accidental one. In fact, it illustrates the lengths to which one must go to trigger the problem in Java. Roger, your question is one that I have shared. I think it's mathematically impossible to deny that the less restrictive nature of duck typing makes it more likely to encounter an inappropriate object. The question, though, is how *much* more likely? As in premature optimization, do we really know that this will be a problem? Or are we incorrectly assuming it? People with much more experience with Ruby than I (such as Dave) report that this is not a problem in practice. I think the minimal risk here needs to be balanced with the formidable benefits of coding in such a highly productive language as Ruby. - Keith |
|
|
Re: Not quite getting it.On May 16, 2008, at 12:45 PM, Roger Alsing wrote: > Ok ok, as I said, I get type promotion. > But what if you assign a "Giraffe" to a property called "Orders" , > isnt > that just as bad or even worse than overflowing a number? then you will need a tall box. a @ http://codeforpeople.com/ -- we can deny everything, except that we have the possibility of being better. simply reflect on that. h.h. the 14th dalai lama |
|
|
Re: Not quite getting it.On Fri, May 16, 2008 at 5:55 PM, Keith Bennett <keithrbennett@...> wrote:
> Florian, your example is not a fair one; it illustrates an intentional > violation of the semantics, whereas Roger is referring to an > accidental one. In fact, it illustrates the lengths to which one must > go to trigger the problem in Java. > > Roger, your question is one that I have shared. I think it's > mathematically impossible to deny that the less restrictive nature of > duck typing makes it more likely to encounter an inappropriate > object. The question, though, is how *much* more likely? As in > premature optimization, do we really know that this will be a > problem? Or are we incorrectly assuming it? > > People with much more experience with Ruby than I (such as Dave) > report that this is not a problem in practice. I think the minimal > risk here needs to be balanced with the formidable benefits of coding > in such a highly productive language as Ruby. > > - Keith I tend to think that using a RDBMS for data integrity with an overlay of Ruby is a nice compromise. I'm still anti-unit_test, but then, I'm not a seasoned programmer and am probably missing the good stuff. With meta: there's a very subtle geeky wet dream underlying the whole concept of meta-programming. I'll stick around and see what happens, but I'll use it sparingly. Todd |
|
|
Re: Not quite getting it.-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1 On May 17, 2008, at 12:55 AM, Keith Bennett wrote: > Florian, your example is not a fair one; it illustrates an intentional > violation of the semantics, whereas Roger is referring to an > accidental one. In fact, it illustrates the lengths to which one must > go to trigger the problem in Java. Actually, you don't have to go that far :). I know, the example is a artificial. Actually, i did only add the interface for illustration. A more common case would be the assumption that methods of subclasses share common semantics with methods of superclasses. I had such a case some time ago, when a fellow student assumed that a method name was not taken and implemented it on a subclass, causing havoc in the code calling it :). Granted, this is an indicator that the naming was too generic, but the language didn't help a bit. But the question was: >How can anyone assume that just because a method exists that the >semantics is the same? This problem is present in both Java and Ruby and none of the languages helps me much in this. It is much more a question of programmers discipline, good naming and knowledge of the ecosystem the software lives in :). Thats perhaps why you don't experience it as a big problem. Considering that i assume that ruby is not the first OOP-Language for many people, they've already got a headstart when it comes to this. But actually, i can produce a real-world sample for an interesting semantic changing behaviour that is much harder to reproduce in Java/C# and would really be abuse in such languages. If you know you way around ActiveRecord, calling #find on associated set of models (e.g. @some_person.friends.find) will not call Array#find but Friend.find. _But_ if you try inspecting the Object, it will happily tell you that it is an Array. (and not some subclass ...) -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.8 (Darwin) iEYEARECAAYFAkguItkACgkQJA/zY0IIRZbmsACgujIPlOK7pEM5AeqEEWLf1aYI mAsAnAjlb3EKVHGFGF/Jn5pBDBVul0AS =aT3y -----END PGP SIGNATURE----- |
|
|
Re: Not quite getting it.-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1 On May 17, 2008, at 1:02 AM, ara.t.howard wrote: > On May 16, 2008, at 12:45 PM, Roger Alsing wrote: > >> Ok ok, as I said, I get type promotion. >> But what if you assign a "Giraffe" to a property called "Orders" , >> isnt >> that just as bad or even worse than overflowing a number? > > > > then you will need a tall box. Pragmatic Programming ;). Roger, just because variables are not typed doesn't mean that you can't check for Types. Actually, Rubys type-system is quite strong, it doesn't allow casts. You can very easily build objekt properties that check for type or a certain set of methods. Something like: class Test attr_accessor :order def order=(order) if order.kind_of?(Giraffe) raise Exception.new("We package nearly everything, but Giraffes????") end end end So Ruby does typing, but on a different level. It assumes that all objects are sane and then gives you the possiblity to check all the information that the object propagates and use that for reasoning. See it as a service-based approach. Wouldn't be the first time a service does not do what the name implies ;). The numbers problem: Conceptually, there is also no such thing as an "overflowing number", in Ruby because Ruby abstracts high enough that you as a Programmer do not have to to care about those technical implications. This is a completely different ballpark ;). Regards, Florian Gilcher -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.8 (Darwin) iEYEARECAAYFAkguJcMACgkQJA/zY0IIRZbWPQCfWGQIQGaBh1LkaHHqcUCtUbpZ GiwAn3pWUIjEvwTubAwgodxuyK1oRLZX =95BN -----END PGP SIGNATURE----- |
|
|
Re: Not quite getting it.> class Test
> attr_accessor :order > > def order=(order) > if order.kind_of?(Giraffe) > raise Exception.new("We package nearly everything, but > Giraffes????") > end > end > end > So is it common practise to do it like this? Eg. does active records have this kind of stuff in the generated code that comes out of "has_many" etc? Anyway, I think I do buy this. Preventing the wrong types form beeing used is pretty much the same as preventing the use of null in C#. It simply become an extra step in parameter validation. And thanks everyone for the replies :-) -- Posted via http://www.ruby-forum.com/. |
|
|
Re: Not quite getting it.Roger Alsing wrote:
>> class Test >> attr_accessor :order >> >> def order=(order) >> if order.kind_of?(Giraffe) >> raise Exception.new("We package nearly everything, but >> Giraffes????") >> end >> end >> end >> > > So is it common practise to do it like this? I wouldn't really say it's "common practice" in Ruby to do a bunch of kind_of? parameter checks; I haven't seen it very often, and if it were the "desirable" thing for a Rubyist to do, the language would do it for you. As you say, this way adds extra steps just to check some stuff that only ultimately has the result of increasing the coupling of your code. Instead, look at it like this: how likely is a Giraffe able to do what an Order does? If the Giraffe doesn't quack like an Order, than an exception is going to be thrown automatically anyway. Just program in it, and see how often it ever actually bites you. Start with small things, work your way up. Read other people's code from time to time. I myself am from a C# background, and probably I really still think that way, but I do like Ruby a lot and I find it fun to use even though my Ruby code doesn't look as "Ruby" as many of the people's here. And do keep in mind that Ruby makes some things quite simple that can be more of a pain to do in C# -- anything involving string manipulation and regular expressions, for example. And the built-in arrays and hashes have a ton of functionality and make stuff really succinct (and gets you away from having to use long nested List<Dictionary<string, Blah>> stuff, or having to cast all the time with ArrayLists, or whatever). The language reads well and makes you jump through minimal hoops; the code you write tends to be shorter and thus easier to digest. It has an interactive mode that's really neat, and you can even use it to check out what methods a given object makes available. The "standard library" is rich and has a ton of stuff built in. And there's a lot of high-quality, free libraries and tools out there that other people have done. Where C# trumps it, in my opinion, is in having a ridiculously awesome IDE integrated with it, and in super easy GUI building capabilities. (There are other more obvious differences, like performance vs. cross-platform capabilities.) There are of course Ruby IDEs (including the SapphireSteel Visual Studio thing or whatever that has Intellisense; I'm sure the guy will be happy to plug it) and you can of course build GUIs in Ruby, but again, it's not about what a language can DO, it's about what it makes easy. So again, just give it a whirl. Outside of whatever your work uses, there's no one forcing you to use one language or another. Try them out, keep an open mind, and go with what feels good. -- Posted via http://www.ruby-forum.com/. |
|
|
Re: Not quite getting it.-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1 On May 17, 2008, at 7:48 AM, Roger Alsing wrote: >> class Test >> attr_accessor :order >> >> def order=(order) >> if order.kind_of?(Giraffe) >> raise Exception.new("We package nearly everything, but >> Giraffes????") >> end >> end >> end >> > > So is it common practise to do it like this? > Eg. does active records have this kind of stuff in the generated code > that comes out of "has_many" etc? > > Anyway, I think I do buy this. > Preventing the wrong types form beeing used is pretty much the same as > preventing the use of null in C#. > It simply become an extra step in parameter validation. > > And thanks everyone for the replies :-) Yes, ActiveRecord checks for the type of Associations. I would not call it "common practice" to rely on the type, but as ActiveRecord maps type Names to Tables, it is desireable to do that. Regards, Florian Gilcher -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.8 (Darwin) iEYEARECAAYFAkgunCkACgkQJA/zY0IIRZYn+ACePMafw/w2cezCc8gSzgdzWBgr uYQAn0RfLmvRqQoztSRSda0FkwHj1V6j =r4bb -----END PGP SIGNATURE----- |
|
|
Re: Not quite getting it.> I wouldn't really say it's "common practice" in Ruby to do a bunch of
> kind_of? parameter checks; I am not a good ruby coder but the code I saw, and my own code as well, rarely uses ".kind_of?" at all ".is_a?" is much more common from my point of view to be seen in ruby code -- Posted via http://www.ruby-forum.com/. |
|
|
Re: Not quite getting it.An interesting example of an intentional violation of method semantics
in the Java standard library is the unModifiableXxx() methods in java.util.Collections. They wrap a collection and override the mutating methods to throw an exception when they are called. So someone relying on add() to add an object because that's what's specified in the interface Javadoc would be quite surprised when an implementation of that interface refused to honor the contract and threw an exception instead. - Keith |
|
|
|
|
|
Re: Not quite getting it. |