37 ms·
Wow, four years already. Maybe you can help settle this question I've had. I'm a rubyist (like you were/are, and wycats, and a bunch of rustaceans), and I think
by losvedir 10y ago
Wow, four years already. Maybe you can help settle this question I've had. I'm a rubyist (like you were/are, and wycats, and a bunch of rustaceans), and I think that sort of drove my interest in rust.
But after 4-5 years of ruby the dynamism which initially was super cool, has grown a little frustrating and I long for a more sophisticated type system and a compile step, since frustrating bugs crop up from time to time that would be caught by that, and which slip through a hole in our test suite.
I've dabbled in Haskell and Rust and the whole "if it compiles it's likely to work, or at least the bugs will be significant logic ones" aspect of them is very cool.
I wonder, though, if the flipside is true? Maybe people who have a compiler and strong type system get frustrated with its rigidity over a number of years, and when they see ruby for the first time are blown away with what it can accomplish. After all, it took a number of years day in and day out with ruby to start seeing its blemishes, I wouldn't be surprised if the reverse were true.
So as someone who's now spent 4 years in the other grass, do you still find it greener? (Or am I wrong from the start, and maybe you like Rust for other reasons and its type system wasn't something that attracted you to it over ruby?)
- shakna 10y agoThe main languages I use with work are: * C * Scheme (Gambit) * Python 3.4 * Pony I find all of them frustrating at times. Python's dynamism is nice, but it's so damn inflexible, requiring my to follow the One True Way. That can be good, and makes it easier to eliminate bad code in reviewing. But it also means that you can fight with the interpreter to do what you want. Scheme gives me both dynamism and flexibility, with less speed tradeoffs. Yay! However, there was someone on my team obsessed with turning everything into a macro. What's the point of first-class functions if you just macro everything? Also, Scheme's stdlib is purposefully small, so you sometimes need to reinvent the wheel. Thankfully Scheme makes it both easy and pleasurable to do so. The rundown is, though fast and dynamic, code review can be painful unless you follow standards, and you might run up against, "Oh... I need to build my own FTP library", though SLIB (depending on your circumstances), can eliminate some of that. C's compiler feels like a breath of fresh air after that. Unless you hit a runtime error, it makes writing code a breeze, quickly and efficiently. Unfortunately, it doesn't protect you against yourself, or lazy people on the team trying to use void pointers for everything. So code review can be harder, and catching edge case segmentation faults can be quite difficult. Enter, Pony. Pony deals with the same areas Rust does, but for reasons I won't go into, when both Rust and Pony were young, my team started using Pony for a few little things. It has been... An experience. Pony is very type safe, it is exception safe, and data race free, all enforced by the compiler. Which sometimes means the compiler will sit there bashing your code for a full day before you realise that you weren't writing it safe enough, and you can't just tweak it, the whole thing needs to be rewritten. Also, the Actor Model being central to everything can be quite annoying, when you just need to fit a couple extra functions in somewhere, but you aren't sure where's best. However: The compiler doesn't let you screw up. What you do write can become massively concurrent fast programs, easily. Pony also has some fairly good documents, for such a young language that really doesn't have the backing of Rust. So... I get frustrated with any language I am forced to deal with over time. I wish Python had compile-time contracts, but there is mypy to ease the pain now. I wish Scheme had a better stdlib, but it goes against the ethos. (See RSR6 community breakdown). I wish C was safer, but it's lack of safety makes it easier to do things like JIT. I wish Pony was more flexible, but it'll never let me point a shotgun at my own foot. If I spend too long in any world... It's time for a breath of fresh air.
- staticassertion 10y agoCan you talk more about using Pony in a production environment? What are the performance aspects of it? How do you find writing 'non-actor' code - like just doing some string manipulation? I find the language fascinating but I'm learning Erlang and I don't really want to get started with Pony at the same time. Do you have experience with Erlang? what made you choose Pony? Sorry for the bombardment of questions but I don't hear much about Pony. As a rust user, and a burgeoning fan of Erlang, I'm fascinated.
- shakna 10y agoI've never met anyone else using Pony in production, so I'll try and give the best answer I can. > What made you choose Pony? We wanted a Type Safe language to run a REST API frontend. That is to say, we wanted to have something that could redirect requests to the appropriate servers, at scale, whilst maintaining Type Safety in the server itself. We got hit by so many issues from JSON's weak/absent typing causing runtime errors, we wanted something that could sanely prove that we wouldn't crash. Whilst we were at it, the same language seemed great for the backend for a couple languages we develop in-house. For example, Owlang is a language developed for teaching with a group of teachers. The first iteration was written in Scheme, today, it runs on top of Pony. We considered three languages: * Rust * Pony * Erlang Erlang was a bit odd to throw in the mix, but we couldn't ignore how amazing BEAM is, especially with recovery by dropping and creating thousands of processes without effort. However, we found Rust was making too many breaking changes, and there was sort of a culture of using Rust Nightly, which doesn't give off a nice solid feel, or didn't back then. Erlang has this sort of huge cognitive overload with it's syntax, making it take longer to learn, for no obvious benefits. Pony's Philosophy[0] however, felt damn good, and we investigated their mathematical proof of safety and the like. > Can you talk more about using Pony in a production environment? Pony's got a few gotchas. Thankfully, they spell them out. [1] We have been burned from long running procedures when we've had to tap out to an in-house C library. We went from using around 400mb of RAM for a group of processes, to running out of memory on a 16GB RAM machine. That was a stupid mistake. However, using a Timer, like the docs tell you to, obliterated that, and we dropped back down to 4-500mb. The non-preemptive nature of Pony's scheduler has taken a few people, myself included, some time to get used to. > How do you find writing 'non-actor' code - like just doing some string manipulation? If you try and avoid the fact you're using Actors, it'll bite you. Pony is designed for concurrency. However, if we're just talking about methods and classes and so on, and how they feel... Pony feels simple, and easy to use. Traits and interfaces make subtyping a breeze, especially interfaces. But, being interested in Erlang, how about some pattern matching? fun f(x: (String | None), y: U32): String => match (x, y) | (None, _) => "none" | (let s: String, 2) => s + " two" | (let s: String, 3) => s + " three" | (let s: String, let u: U32) if u > 14 => s + " other big integer" | (let s: String, _) => s + " other small integer" else "something else" end One more bonus for something Pony has, that proved unexpectedly useful, is the ability to have multiple, or generate, Environments. In terms of Pony, that means argc, argv, argp. Being able to isolate environment variables between processes has been useful for making some configuration easier. [0] https://tutorial.ponylang.org/#the-pony-philosophy-get-stuff-done https://tutorial.ponylang.org/#the-pony-philosophy-get-stuff... [1] https://tutorial.ponylang.org/gotchas/ https://tutorial.ponylang.org/gotchas/
- oxymoron 10y agoI've worked primarily in Java and C++ for the past few years, but also with several dynamic languages. I sometimes miss the expressiveness of Python, but I can't say I'm ever frustrated by a strong type system nor does the compile step annoy me as long as my write-compile-test cycle is reasonably quick (usually achievable). With Java 8, and even more so with Rust, I'm less frustrated by the lack of expressiveness, so I find myself missing dynamic languages even less.
- flukus 10y ago> but I can't say I'm ever frustrated by a strong type system Never? I can't say it happens very often but occasionally the type system get's in the way, usually when you want the function to be type T1 but sometimes it'd be convenient to do a little bit more if the type is also T2.
- smaddox 10y agoRust supports algebraic types and switching over the type, which handles your example quite efficiently. You would simply define an algebraic union of T1 and T2, and switch on the type into the desired code for each branch.
- flukus 10y agoWhat does that look like in code? I was using c# so I did the dirty: T1 arg; var foo = arg as T2; if (foo != null) .... Also, how do we format code here?
- shakna 10y agoI expect Rust should be able to handle this nicely, but I'm more familiar with Pony... So here's how to do it nicely in it: fun f(x: (T1 | T2 | None)): ReturnType => match x | T2 => /* do something */ | T1 => /* do something else */ | None => /* Handle badly behaved. Optional to have, compiler can enforce good behaviour if you want. */ Note: You can see formatting at https://news.ycombinator.com/formatdoc https://news.ycombinator.com/formatdoc
- tatterdemalion 10y agoLanguages I use most are Rust and Ruby. I find the type system not frustrating, but challenging, on occasion. But only when I'm trying to write a library with a very convenient, flexible API. Its probably easier to write the first draft of this sort of library in Ruby, but in my experience what the library does under edge cases and bugs is often super unpredictable. Not so much in Rust. I haven't had these frustrations in application code in Rust.
- flukus 10y agoHave you tried crystal? Looks like it could be the best of both worlds.
- prewett 10y agoAre you talking about strong typing or static typing? I've been using statically typed languages for 20 years (C++, Java, Objective-C) and I haven't gotten tired of it yet. Especially when working in a large code-base I didn't write, Python is rough. What's a "session"? Who knows, guess I'd better put `print type(session)` and figure out how to get that function executed. Although, the thing that bothers me about Python (haven't used Ruby) is the fact that it is interpreted. It's really annoying to have to run my program to discover syntax errors and typos, when a compiled language would do that for me. With interpreted and dynamically typed languages, you have to have 100% test coverage, because you have no idea if your code is even syntactically valid until you run it, and of course if it isn't valid, then you throw an exception. (Hopefully that crashes the program, unless someone was brilliant enough to catch all exceptions and not print any error messages, then it looks like everything worked fine until you discover it didn't.) So every change is a potential for an exception, until you execute that line of code to make sure there wasn't a misspelled variable name or something. So, yeah, I love the compiler. (I also love Python for scripty stuff.)
- smaddox 10y ago> With interpreted and dynamically typed languages, you have to have 100% test coverage, because you have no idea if your code is even syntactically valid until you run it, and of course if it isn't valid, then you throw an exception. I think you mean _semantically_ valid, e.g. no undefined variables. Most dynamic languages provide file-level syntax checking, rather than line-level. But I completely agree that this is the easiest argument against dynamic languages. Computers are better at bookkeeping than humans, and we should use them as such.
- gedrap 10y ago> until you execute that line of code to make sure there wasn't a misspelled variable name or something But isn't it the purpose of tools such as IDEs? PyCharm is pretty damn good at it. Of course, it's not always possible or convenient firing up an IDE. But I suppose editors such as vim should be fully capable of doing this via plugins as well.
- 10y ago
- kazagistar 10y agoIts nice to "take a break" from static types once in a while and hack together some kind of data munging script in python every once in a while. But every time I have tried to go larger in scope I ended up regretting it. I'm not sure I would want to do any kind of dynamically typed programming professionally again.
- steveklabnik 10y agoThis is very thoughtful :) So I _do_ like Rust for other reasons, or at least, I did initially. My opinion has changed over time. I used to say "I'd never write web application in Rust," but soon, I'd prefer it slightly. Needs some more libraries to come out, and they're close... There's two sides to "is the flipside true"? One is, there's a huge variety of static type systems. Some of them are more flexible than others. So for example, if I had to use Java 1.4, or even Java 1.5 (which are very old, but were two releases I am very familiar with), I'd wish I was back in Ruby. This is because it's _too_ rigid; I can't express enough things in the type system to make up for the lack of flexibility. In a language with a better type system (and Java itself has a better one today, even), it changes the value of the equation. In Rust though, there's another axis: speed, memory usage, stuff like that. I don't miss Ruby's flexibility here, because even basic operations in Ruby are _so so so_ much more expensive than in Rust. So when I think "oh yeah, I could do that, but if I think about how Ruby does it under the hood... it's not worth the cost." This makes me miss Ruby less as well. Ruby is an excellent language, and I will always love working with it. But there's only so many hours in the day, and I've spent so much time with it already...