5 ms·
I've never quite understood the notion that languages like Python and Ruby are amenable to fast prototyping. Ultimately, you wind up just having to carry compli
by zapzupnz 7y ago
I've never quite understood the notion that languages like Python and Ruby are amenable to fast prototyping. Ultimately, you wind up just having to carry complicated type information in your head rather than write it all down in your code, all whilst the compiler utterly fails to help you in any way in case your memory ain't what it used to be.
I'm sure those languages and their ilk have advantages for prototyping, but I agree, mandatory typing in other languages isn't a burden. If you already have to reason about what arguments are acceptable in functions, what objects can receive what messages and what those messages should contain, you already have typing — just inefficiently stored in short term memory.
Those who are the biggest proponents of these languages as useful for prototyping are also not the ones who rewrite their code in type-safe languages, so being able to add type annotations for the sake of their colleagues who eventually have to turn these prototypes into code upon which a team can collaborate can only be a useful thing.
- nemothekid 7y ago>I've never quite understood the notion that languages like Python and Ruby are amenable to fast prototyping. I've thought about this for a while and I think the "fast prototyping" reputation is an accidental feature that sticks because of history. Python and Ruby were just better languages than Java 1.4, C++, Perl and PHP were at the time. They were so much better for not only prototyping, but writing - it was easier to get something working and iterate in Python than it was in Java. And not only were they better, they were better at the right time when the internet exploded. Now, it largely feels like languages like Java and newer languages like Go have caught up, but Python and friends still enjoy the feature of "fast prototyping." Now I think this is because since they had gotten so popular, they now have a massive ecosystem of libraries and idioms that makes it so easy build applications.
- kyllo 7y agoJava and Go today are much better to work with than Java was in, say, the early 2000s, but to realize the productivity boost of a dynamic language within a statically typechecked language, you need type inference and a REPL. You still don't get this with Java or Go, but you certainly do with ML-like languages (Haskell, SML, OCaml, F# etc.) A lot of Haskell developers will tell you that writing Haskell feels a lot like a functional Python, and they use Haskell for scripting as well as application development.
- cutler 7y agoUntil Java gets data classes it will make you miserable. Lambdas are clunky in Java at best. "Much better to work with" than Java 1.3 is setting a pretty low bar.
- philwelch 7y ago> Until Java gets data classes it will make you miserable. https://projectlombok.org/features/Data https://projectlombok.org/features/Data
- pjmlp 7y agoJava has repl support since Java 9 and before that there were interactive sheets like Eclipse scratch pad, which alongside incremental compilation were already quite good. And while Java's type inference is not the same has having HM around, it is already q89te friendly.
- fouc 7y agoI think ruby has a reputation for "fast prototyping" for a few reasons 1) readable (somewhat english-like syntax) 2) terse (short and to the point, no extra setup code needed) 3) meta-programming/DSLs It still remains unbeatable for readability and terseness..
- nitrogen 7y agoDon't forget 4) no compilation/ultra fast test cycle and 5) REPL (IRB or Pry)
- cutler 7y agoYes, and it's for this reason that adding a type system will to it will alienate a lot of its users. You can say "optional" or "gradual" as much as you like but adding types will split the community which is the last thing Ruby needs right now. The trouble with tech is we just can't let something be and stop fiddling with it. Ruby is fine just as it is.
- bhaak 7y ago> Ruby is fine just as it is. Which Ruby do you mean? 1.8, 1.9, or a more current one?
- zapzupnz 7y agoThis response makes sense to me.
- adambard 7y agoI think it has less to do with the languages themselves, and more to do with the frameworks available, and the metaprogram-y things those frameworks are free to do without a type system stopping them. I've yet to see the equivalent of Django or Rails when it comes to rapidly assembling a database-backed CRUD app in a statically typed language.
- chessturk 7y agoMy job has internal tool that reads MySQL schemas and outputs a CRUD golang api and json-based form uis to interact with them. I think it could be it's own product, but leadership doesn't care.
- vinceve 7y agoI am working as a java developer now for about 3 years. Before I worked 5 years with rails. You are completely right, a spring boot application with Lombok doesn’t come near a rails application. Also what people tend to oversee is that the recompilation step really takes a lot of time.
- neetdeth 7y agoTheir reputation for fast prototyping was established before type inference became a widely available language feature. Duck typing is also a minor win for "do what I mean" generics - you never have to worry about the type specification being too narrow, just pass an object with the necessary methods and it'll work until it breaks.
- jonnytran 7y agoThis is a straw man argument. Sure, if your types are simple like int, string, or float, you might as well write them down rather than keep them in your head. They double as documentation. However, the other cases are where it matters. 1. When the types are complicated enough, people no longer read them. They skim over them and don't bother to ever "load" them into short term memory. Sometimes it makes sense to make a type alias for the subcomponents, but many times they're one-off types and it wouldn't make sense. As the person writing the code, figuring out what the types actually are and writing them down doesn't actually help anyone. It's just busy work that the compiler or interpreter could have inferred. For example, if I have a hash nested in an array, nested in a set, you can access them all with brackets chained together. I don't actually need to know the full type in order to use it. So why bother figuring out the exact type that it is? Which brings us to... 2. When the types are abstract, with type variables and type constraints, someone has to put in the work to come up with the most sensible type signature. Sometimes that is the most general type that the code satisfies (using a Rust trait, Haskell typeclass, or a Java interface), but sometimes it's not. It really depends on the context. Should I abstract over this type and introduce a type parameter to the function? Or should the type parameter be for the entire struct/class? These are oftentimes complicated questions, with no clear answer. Weighing your options and choosing is real work. If I now say that this function will accept different sized ints, I may no longer be able to just call i64::something(). I literally need to change how I write my code or even import a new helper library to do it. (I have had to do that in Rust. And I love Rust, BTW.) OTOH, in a dynamic language, all of that work is just gone. What I'm saying is that types for a compiler must be precise and general. But types that you keep in short term memory are oftentimes vague (something that I can index, or some kind of number) or specific to a test case. And it doesn't matter.
- zapzupnz 7y ago> This is a straw man argument. That would imply ill intent on my part, and there was nothing of the sort. All I said was that I couldn't see the sense in certain things and, without further explanation, I didn't. Other comments helpfully pointed out the context for why the assertion is so often made and I was happy with it. On the other hand, I think I'd need to see some hard evidence for the following assertions: > When the types are complicated enough, people no longer read them What is a complicated type? > As the person writing the code, figuring out what the types actually are and writing them down doesn't actually help anyone. Citation needed. I find static typing tremendously helpful in my own code, especially if it's code I haven't worked on in a long while. > It's just busy work that the compiler or interpreter could have inferred … such that I only notice errors when the code is running, not beforehand. Without type annotations, interpreted languages like Python and Ruby are happy to let wrong types in function calls and message passes slide — which is why frameworks like Sorbet exist, to help eliminate that class of error. > 2. All of that is language-specific, surely, not really anything to do with static or dynamic typing. That whole mechanism is quite straight-forward and has a well-prescribed mechanism in Swift, for instance, with protocols, extensions, and conditional conformance. > OTOH, in a dynamic language, all of that work is just gone. I mean, it's not just gone. There are trade-offs, of course there are; but the assertion that the work is gone also implies the potential associated errors are gone seems a bit ingenuous to my eyes. Yeah, types can be a bit constraining — but at the same time, if you reason about them properly and according to the language's prescribed mechanism rather than fight them, it can and does become second nature. At that point, using types becomes as simple for some as not using types is for others.
- tomp 7y agoI am an "expert" in static type systems (I'm familiar with Java, Scala, OCaml, Haskell, Rust, Go, TypeScript, C++ ... and keep up to date with latest type systems research like 1ML, MLsub, Liquid Haskell, ...), but I have a really hard time imagining how one would develop a statically typed library that would even approximate the usefulness and convenience (for rapid prototyping and interactive data analysis) of Python's Pandas (although if I was a betting man, I'd wager the best language to implement it in would be Scala, with it's advanced macros & almost-dependent type system).