Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I recently talked to a friend of mine who expressed the frustration of not knowing what a function returns because it's a language without static typing. It was something I hadn't thought of before personally. I thought about it a bit and realized that as a Ruby programmer, I depended on two things to figure out what a function returns, and neither is the source or documentation (most of the time at least):

1) a REPL. Just give it a whirl and see what you get.

2) intuitive method names and good abstractions. If I call @user.posts in a Rails app, I can assume I will get an Array-like object that I can treat as an array without any problems. The actual type does not matter 90% of the time.



> a REPL. Just give it a whirl and see what you get.

A REPL is in no-way tied to having a dynamically typed or interpreted programming language. E.g. Haskell's GHCi has an excellent REPL environment where you can, in addition to evaluating code, ask for the type of an expression and do other static analyses.

I agree that a REPL makes a huge (mostly positive) difference on how you write code.


that's one aspect of dynamic typing that i strongly dislike. you can't figure out what a function does by looking at its signature. if documentation is absent (which is almost always the case), a coding task turns into a reverse engineering task.


A good repl that automatically prints out the function's heredocs is usually enough for me. I like bpython particularly because it shows the argument list and the heredoc as soon as you type the opening parenthesis for a function call. In other REPLs you can usually call a docs(fn) or a source(fn) to handle the rest.


So you basically put type information in the names. That's typing in a sense.


I see where you're going but thats not really what we're doing with that ... @user.posts actually returns an array of posts and @user.posts.first returns an actual Post object.

You could also change @user.posts to be @user.contributions, for example, and that would hide the fact that contributions was just an array of Post objects.


No, he puts typing in the interface, and that's indeed typing in a sense, called duck-typing.


I think we are talking about different things. Duck-typing doesn't help in depicting what the return type of a function is when looking at the function signature only. You need to look at the function implementation (the actual duck) to tell what the return type is.


My point I guess was that with proper abstractions and duck typing you really don't have to care about the type. I only notice something isn't a duck when I try to use it like a duck and it fails - which is surprisingly infrequent.


It becomes difficult to tell it's a duck when reading code, which was the original complaint. Duck type works when you actually try calling it.


> a REPL. Just give it a whirl and see what you get.

In a large system you might have to jump through a lot of hoops to get an accurate result from the REPL. What if the thing you're trying to puzzle out is 20 call levels deep? As a new Ruby dev I struggle with this.


In python if I was trying to figure out something complex 20 levels deep, I would stick in an "import pdb; pdb.set_trace()" to get a REPL at that spot. There's probably an equivalent for Ruby?

(Off-topic, the werkzeug debugger even lets you debug browser apps by jumping into a REPL anywhere in the stack trace, in the browser, after an exception is thrown. I think it also has a command that bakes you a pie.)


If it is a pure function it makes the call depth irrelevant. While not always the case, it seems to be pretty common in Ruby development to keep things as pure as possible.


No, it's not irrelevant. If you're trying to figure out what gets passed up the call stack, you need to trace it through. Being able to plug in your own values into a single method call via the REPL isn't helpful if you're trying to analyze what really happens when it runs. Either you need to run it under a debugger, or manually trace it through. In a static language you just have to read the type signatures.


As mentioned by JackC, if you need to understand the context in which a method is called, use a REPL. But to understand what a pure method does should be context free, by definition.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: