7 ms·
Confessions of a Ruby Developer Whose Heart was Stolen by Scala
- Stranger2013 13y agoWell, of course a classic programming language is better then a script language for majority of tasks. Script languages like JS and Ruby just should not be abused and should only be used as a very thin layer on top. E.g. GUI scripting.
- aaronbrethorst 13y agoI would recommend that you immediately inform Yahoo, 37 Signals, Hulu, GitHub, Penny Arcade, and every other Node, Rails, Sinatra, and EventMachine user of this fact! Also, Tcl/Tk called and wants its use case back.
- unono 13y agoWhy do microsoft and google insist on static compiled languages?
- Stranger2013 13y agoGoogle are trying to use Python as well. But they are probably forcing the best practices as well - otherwise it's a mess.
- marshray 13y agoBecause they allow us to put very useful limits on the degree to which changes in a large and evolving codebase will violate the expectations of developers. When adding and changing code in large collaborative projects, the primary question in every developer's mind is "OK, what else depends on this, i.e., what is possibly going to break?" This goes back to the old wisdom of separating interface from implementation. Highly dynamic languages, such as Ruby, certainly have their advantages too. But programs in languages which enable, if not encourage, developers to add new methods to the integer '5' can quickly become very difficult to reason about. Static, strongly-typed languages also provide other benefits such as much better error checking and compile-time optimization.
- alinajaf 13y ago> But programs in languages which enable, if not encourage, developers to add new methods to the integer '5' can quickly become very difficult to reason about. Can you give me an example of a single ruby developer who thinks this is a good idea when writing new code/a library?
- ldub 13y agoWhen I began learning Ruby, this was one of the first exercises in the first chapter of the book I was using. They had you write 3.minutes, 3.hours, 3.seconds, etc. I can find the book if needed. It may be true that strong ruby developers likely will not do this, but then why teach bad practices to beginners?
- marshray 13y agoI think probably for every language, every development team needs to have agreements not to do certain things. The probability of a developer doing something unexpected increases exponentially with the number of developers and the amount of code. It only takes one, but here are a few thousand to start with: https://github.com/search?l=Ruby&q=%22class+Integer%22&ref=advsearch&type=Code https://github.com/search?l=Ruby&q=%22class+Integer%22&ref=a... Do your projects use any Gems that are pulling in any of this code? Could they change to do so in the future? Most importantly: how much effort is it for you to definitively answer this question? Our task is that of proving a negative (which as we all know is very difficult). Namely that there is no other code that is relying upon the behavior that you are changing. When there are reasonably well-defined interfaces between components it dramatically reduces the possibility space for implicit dependencies and interactions. So this is a slam-dunk case where tools can make our job much easier. Without tools, we're basically reduced to "verbal lore" and "honor system". Programmers have to rely upon the shared understanding and behavior of other humans in order to reason about their own code.
- unono 13y agoFully agree, I'm a ocamler myself, was trying to make parent op think. Companies with dynamic language codebases should be fearful of the technical debt they've accrued (and hire us static guys to fix it!).
- csense 13y agoI've been thinking about private fields lately. In Python, a private field starts with an underscore, and someone who knows the culture of Python knows that the initial underscore encodes the notion "This field is not considered to be part of this library's public API, and it may go away or change behavior at any time, not necessarily a major version bump of this library, and if you look at it or change it, you'll be responsible for maintaining your code when we break it. Also it's probably totally undocumented, so you'd better read the library code to make sure it does what you think it does before you use it." A good developer will weigh the work that can be accomplished today by using the private field against the future consequences of the underscore's admonition, and come to a wise decision -- if (s)he decides to use the field, the Python language will defer to the programmer's human judgment and allow it. A mediocre developer won't understand the underscore's implications, and will blithely use private and public fields in exactly the same way, because Python won't stop them. In Java, the language itself will prevent this from occurring -- a private field, in Java, is really private. So the compiler [1] prevents mediocre developers from producing brittle code by referencing private fields everywhere. If you have a lot of mediocre developers in your organization -- which IMHO tends to happen more in larger organizations -- then you want a stricter compiler to stop them from writing unmaintainable code. I personally prefer the Python way, simply because I've been bitten by this Java "feature" on multiple occasions -- a third-party library marks some field as private, but I really want to use it, to the extent of being willing to deal with instability by updating my code or freezing the dependency, if necessary. But I can't, without making my own fork of the library. [1] The runtime also prevents private field access. So even if you bypass the compiler's checks by patching it or hex editing the compiled bytecode, you'll still get runtime errors from trying to read private fields outside the class where they're defined.
- Stranger2013 13y agoJava does not allow using reflection to access private fields !? Dude, just use C#.
- csense 13y agoYou might be able to do it if you replace the SecurityManager or something. We may laugh now, but it actually seemed like a good idea at the time. Remember, a big part of Java's early use case was running untrusted remote code ("Applets") in the browesr without prompting the user (a niche now filled by JavaScript [1] and a declining Flash). Which means you really don't want that code to be able to bypass all your security by using the reflection API to read and write things it's not supposed to. Applets never really caught on, but now the language features are constrained by backward compatibility. Also, C# isn't supported on Android AFAIK. [1] Mostly unrelated to Java despite its name; see http://en.wikipedia.org/wiki/Javascript#JavaScript_and_Java http://en.wikipedia.org/wiki/Javascript#JavaScript_and_Java
- Stranger2013 13y agoThose companies are using it properly though, don't they?
- aaronbrethorst 13y agoWho are "they"?
- hamidr 13y ago"Those companies" referring to google and MS.
- csense 13y agoI go the other way -- I write in Python by default, then only go to another language if I specifically need it, for example these scenarios: (a) Python isn't fast enough, and Pypy doesn't make it fast enough, or isn't a viable option in the target environment. So you write in C, OpenCL or assembly language. (b) A vital library or other dependency can't talk to Python and you can't quickly find or write a reimplementation or bridge. (c) Python isn't supported in the target environment, for example, the web browser [1] or the iPhone. [1] Yes, yes, I know, things like Skulpt and Pyjamas exist. But I think those dependencies are too heavy for a lot of projects.
- jitl 13y agoAs a Ruby developer, I can't get through these sorts of slides. My other languages are C, Go and JavaScript, and the Scala syntax is totally inscrutable to me. Isn't the point of slides presenting something that can be easily absorbed? And I can't just quickly look up these declarations either — Scala is too complex for that given my experience level. Is there a gentle introduction talk for Scala around so I can evaluate the language without putting in a week of learning?
- vladev 13y agoYou might try Venkat Subramaniam's Scala for the Intrigued [1]. He's a very good speaker. Regarding Scala's complexity - some more advanced features are presented in those slides. Imagine watching a talk about Python where they talk about decorators and meta-classes. [1] https://www.youtube.com/watch?feature=player_embedded&v=grvvKURwGNg https://www.youtube.com/watch?feature=player_embedded&v=grvv...
- Stranger2013 13y agoConsider F# then.
- trailfox 13y agoAs a Scala programmer I find Ruby syntax complex and inscrutable, almost like Perl.
- prollyignored 13y agoYou have a tumor in your brain.
- csense 13y agoAs a Python programmer, I agree. Here's a Ruby snippet. I don't want to pick on this particular project [1], rather, I've found that this is typical of Ruby code: state_machine :state, initial: :active do after_transition any => :blocked do |user, transition| # Remove user from all projects and user.users_projects.find_each do |membership| return false unless membership.destroy end end My conclusion? Ruby's syntax is awful. There are colons, absolute value bars, implications, and who-knows-what-else flying everywhere! It gets worse, elsewhere in the same file there are messy lines like this one with single-arrow implications, question marks and ampersands [2] [3]: scope :not_in_project, ->(project) \ { project.users.present? ? \ where("id not in (:ids)", ids: project.users.map(&:id) ) : scoped } Simple, intuitive syntax? From where I sit, the syntax of Ruby is worse than C++, and approaches Perl levels of awfulness. In most languages, I can at least sort-of grok what's going on from the context when I see unfamiliar operators, but not so in Ruby. This is a copy-paste of a comment I made [4] weeks ago on another article. [1] https://github.com/gitlabhq/gitlabhq/blob/4caaea824cf51670d11b409efa5701dd74614d2a/app/models/user.rb#L118 https://github.com/gitlabhq/gitlabhq/blob/4caaea824cf51670d1... [2] https://github.com/gitlabhq/gitlabhq/blob/4caaea824cf51670d11b409efa5701dd74614d2a/app/models/user.rb#L143 https://github.com/gitlabhq/gitlabhq/blob/4caaea824cf51670d1... [3] I split the line and inserted backslashes because HN gives me a horizontal scrollbar when it's a single long line; apologies if this transformation isn't legal Ruby, or changes the meaning of the code. [4] https://news.ycombinator.com/item?id=5784296 https://news.ycombinator.com/item?id=5784296
- playing_colours 13y agoThe speaker pays a lot of attention to implicits in Scala. Well, it's a powerful tool, elegant solutions can be built with it, but you should be careful using them. Implicits bring its own magic and abusing them can pollute your project, make it difficult to understand the code. Maybe the speaker is so attracted to inplicits because they remind him of Ruby's / Rails' magic?
- vladev 13y agoYou are correct that implicits are a sharp tool. Thankfully, the Scala community knows that nowadays and they are used for a fairly small number of cases - pimp my library (add methods to Ints, Strings, etc.) and typeclasses.
- trailfox 13y agoFor those interested in learning Scala I'd recommend the free chapters from Scala for the Impatient: http://logic.cse.unt.edu/tarau/teaching/SCALA_DOCS/scala-for-the-impatient.pdf http://logic.cse.unt.edu/tarau/teaching/SCALA_DOCS/scala-for...
- pyvek 13y agoAlso, _Functional Programming Principles in Scala_ course on Coursera by Martin Odersky (Scala's designer) is very good. https://www.coursera.org/course/progfun https://www.coursera.org/course/progfun
- dhugiaskmak 13y agoI just finished the most recent session of this class and I found it incredibly frustrating that there was no discussion of the homework assignments after the due dates had passed. What's the point of having homework if there's no way to get the correct answers and get feedback on your solutions? And take the "in Scala" part of the course title with a grain of salt. You're only taught enough to complete the exercises.
- hejsna 13y agoIt seemed like most of his slides came down to the old typed/untyped flame war. Yes, in Scala you can look at your objects in an IDE and be told what type they are, in Ruby you can't. Some organizations and people need that, some don't. And yes, it's easier to optimize typed languages. Some applications need that extra speed, most don't. I'm happy he found a language he enjoys working with, but I doubt this will change anyone's mind...
- coopdog 13y agoSomewhat true but I find Scala's inferred typing a surprisingly great compromise between the two. For example: val i = 1; i = "some string" // throws a compiler error, because it knows i is an integer It's great when you haven't declared the types, you change for example an int to a double or a class to some other class (eg swapping a data structure) and it just flows through the code base without problems like a dynamically typed language. It can also be pretty useful to look up types when they get complex in the middle of some function, like a Map[List[(String,SomeObject)]] (a map of lists of (String,SomeObject) tuples). Allowing the types to get complex lets me focus on the problem while giving a crutch to quickly remember where it's at half way through (and while finding other methods/source of data) and keep moving towards the solution.
- BonoboBoner 13y agoScala is a fantastic language, but my heart seems to resist due to things like this (slide 27/42): implicit class RichSeq[A, C[A] <: Seq[A]](underlying: C[A]{ def cycle: Iterator[A] = { lazy val circular: Stream[A] = underlying.toStream #::: circular circular.iterator } }
- vladev 13y agoThis is very dense code, and takes some getting-used-to in order to read. What it achieves is beyond the reach of many languages. All it does is convert a Seq (sequence) to a lazy stream that will infinitely cycle through the values. Seq(1, 2, 3).cycle.take(8).toList res3: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2) It will work for any seq-like structure (including List. Vector, Queue, etc.) If you try to use it with anything else, like a Map, it won't compile. Also, note from my example that it's generic and the resulting List is of the correct type. Just like novice JavaScript developers struggle with "Why 'this' changes here?", it requires some experience with the language.
- Stranger2013 13y agoBrainfuck language is even denser.
- dons 13y ago> This is very dense code, and takes some getting-used-to in order to read. I don't think so. It is full of syntactic noise, for what is really just notation for building a cyclic structure. * type annotations stated explicitly, not inferred * type variables given multiple times * too much non-verb, non-noun syntax e.g. `#:::` * and the actual construction of the cycle is stated imperatively with great ceremony (despite it being an applicative) It is the opposite of dense.
- prollyignored 13y agoAttention to syntax is what ruby is good at. Scala, Haskell treat syntax as a chore.
- gizzlon 13y agoThey way you'd build large systems in dynamic languages is to break it up into many smaller pieces that work together. This frees you to change parts without worrying about the rest. To me, this type of development is much more natural and sane than the "one big clusterfuck" type of projects I've seen in Java et.al. Edit: Also, dynamic languages let you make the tradeof between safety and speed. Sometimes you go slow and steady (simple code, tests..) and sometimes you just want to test something out.
- mattquiros 13y agoHm, I don't know what you've seen but I'm pretty sure Java is about breaking up large systems into many smaller pieces that work together, instead of one big clusterfuck. Must be some really badly designed system, more of a programmer's fault than the language itself
- gizzlon 13y agoTrue, but isn't it still one big program/project? What I mean was to break it up into many smaller programs and (possibly) projects (think unix process vs. classes =)
- sandGorgon 13y agoCan someone comment on the current state of tooling in the Scala world. Last I had tried (some months back), SBT was extremely slow. Googling about SBT came back with a lot of complaints about the state of scala tooling back then.
- yareally 13y agoI've been using Scala on Android + Intellij IDEA for about the past month after wanting to try something new[1]. Other than having to run it through proguard first, the compile process in Intellij is comparable to how it is with just Java. Scala plays nicely with Android and I have loved using it so far. Makes Android development a bit more fun than with just plain old Java. [1] https://github.com/yareally/android-scala-intellij-no-sbt-plugin https://github.com/yareally/android-scala-intellij-no-sbt-pl...
- sandGorgon 13y agoah - "Using proguard lets you build Scala without any extra plugins and sbt fiddling". Seems like the tooling is still one of the more painful aspects of Scala. Kudos to Intellij, -1 to Scala.
- yareally 13y agoYeah, if I had to manually fiddle around with the SBT build process and manually adding dependencies instead of letting Intellij handle it all, I would be less motivated to want to switch away from Java on Android for sure :). Excessive configuration to get a new project up in a running is a major demotivator sometimes when you have a new idea and want to just start coding right away.
- th0br0 13y agoDo not forget, however, that (for development) you can easily skip the Proguard step if you install the scala libraries on your device directly. Also, setting SBT up is pretty much a one-time thing. Afterwards, you only need to do a few tweaks when starting a new project. I've used Scala for a couple Android apps in the past... it was great fun to do so! Still, AndroidAnnotations not working with Scala code requires you to rewrite some of their functionality... but you can do that rather easily with Scala's traits etc.
- dgregd 13y agoI just wonder when someone will build a tool to annotate Ruby, Python source code with var types gathered during run-time. If C has Valgrind then dynamic typed languages should get something for the types.
- Erwin 13y agoPyCharm does this. In addition to doing type inference while you have your project open, you can while debugging it run it and make it collect type information. That's quite a bit slower than usual, but once done you will get extra type hints of possible types passed to your functions. http://blog.jetbrains.com/pycharm/2013/02/dynamic-runtime-type-inference-in-pycharm-2-7/ http://blog.jetbrains.com/pycharm/2013/02/dynamic-runtime-ty...
- yareally 13y agoPython 3.0 has the Gradual module[1][2]. [1] http://ecee.colorado.edu/~siek/gradualtyping.html http://ecee.colorado.edu/~siek/gradualtyping.html [2] https://pypi.python.org/pypi/gradual https://pypi.python.org/pypi/gradual
- garysweaver 13y agoRuby and Scala are for two different kinds of environments. One is an environment where having less code to maintain (that can also be highly legible) matters and where you have a lot of options. The other is an environment where an edge in performance is more important, but not important enough to write it in an even faster language/not run in the JVM at all. I noticed a lack of a link to a 1:1 comparison of application code with realistic examples. I think such comparisons and related discussion are often the best way to convince someone to use a language. And some slides were just blatantly wrong, like Mixin Abuse: apparently that is just a long list of module includes? I have never seen so many module includes in a single class in application code. But, assuming you did have that, you should show what it would look like side-by-side in Scala. In Ruby, there are a lot of options when it comes to including other code or defining code in a class, instance, etc. Those options can lead to much less and more legible code if used correctly. I remember when people said Java was slow; they made it seem like it was a fad, and no reputable company would use it. And... we see where that went.