Earlier quoted context omitted.
TDD can help with this. I more often than not, will write a unit test or functional test first, then work on the code for that test where I'm just running that one test until it succeeds. After I have individual parts working, I will integrate everything, which again will just be another integration test run from the IDE. I realize this isn't always possible, and is probably easier to do in a managed language, but yo…
It's true, but it's more a treatment then addressing the root cause. Rich Hickey, creator of Clojure has a fun quote that goes something like: "You thought you wanted TDD, but really you wanted an interactive REPL." My gripe with TDD, is that it gets tedious in its own way. Always needing to eventually mock some aspects of the code, and always working in the small, you start feeling distant from the medium and large…
Fun vs. Computer Science (2016)
121–130 of 184 posts
Re: Fun vs. Computer Science (2016)
#122I feel like this is a false dichotomy: you can have a fast iteration cycle, and have statically checked guarantees. I've worked in Haskell for 7 years and had exactly this. I could load my entire app in GHCi, make changes, reload and test. Now I'm working in Java and in IntelliJ I can have something similar with hot-swap. And in the browser with typescript I have a strong type-system and can reload my app in seconds.…
Well, yea, hopefully in the future we have languages that allow both. I do feel like research in language design has ignored the interactive and fast feedback loop aspect though, at least from the reasearch I know of. My biggest gripe with static checks, is that in reality, most of the software most programmers are asked to write don't need to have 100% correctness. As long as 95% of the most likely to occur and the…
Re: Fun vs. Computer Science (2016)
#123Earlier quoted context omitted.
> find the process of fixing type errors quite enjoyable I, myself, would rather be creating new functionality than fixing a litany of type errors. In fact, I'd rather go to a meeting than change several hundred instances of 'duck' to 'waterfowl', 'avian', and 'ugly_duck' (knowing that I'll probably have to go back and change it again later). Different strokes for different folks, I guess.
Well... but usually those are actual errors that you would need to fix anyway.
Re: Fun vs. Computer Science (2016)
#124Earlier quoted context omitted.
> find the process of fixing type errors quite enjoyable I, myself, would rather be creating new functionality than fixing a litany of type errors. In fact, I'd rather go to a meeting than change several hundred instances of 'duck' to 'waterfowl', 'avian', and 'ugly_duck' (knowing that I'll probably have to go back and change it again later). Different strokes for different folks, I guess.
What you are saying is like the people that would "rather write new functionality than tests"... Like, yeah, that would be nice, if you were able to write 100% bug free code, but you aren't so your tests are actually important in the goal towards a working product.
Why? Unit tests also check a lot more than the types being passed around, so they are a lot more useful in the long run. There are some type systems where this is perhaps not the case, but they certainly aren't the majority. The majority is "so do I go with a float or a double" or "I have to cast this int to an uint64 for this one function".
Re: Fun vs. Computer Science (2016)
#125Earlier quoted context omitted.
When showing off Clojure the application is often molded while running by patching it via the repl. But what I don't understand is if you can actually develop real programs like that? Surely even in Clojure code there are lots of dependencies so you can't just change one place in isolation. And I also guess that changes done on the repl aren't actually saved for the next time you run your app? And how do you do testi…
The trick with some of these runtimes (I don't know if Clojure does this, just noting that the paradigm exists) is that the state of the runtime is not lost when going from development to production. The entire state of the program, including the code and the globals in memory, is preserved, and simply spun up in a different environment. This tripped me up for some time with Smalltalk - I didn't understand this. It's…
Can easily add a REPL to any Clojure program though.
Re: Fun vs. Computer Science (2016)
#126Agree whole heartedly! That's why my favorite language is Clojure. That interactivity, instant feedback, seeing the program running as you are tweeking it, its a bliss to use and it creates better more functional software. Imagine playing music as you hear it when trying to come up with a good melody. Now imagine not playing it, but composing it on music sheets instead, and occasionaly playing what you've got every 1…
When showing off Clojure the application is often molded while running by patching it via the repl. But what I don't understand is if you can actually develop real programs like that? Surely even in Clojure code there are lots of dependencies so you can't just change one place in isolation. And I also guess that changes done on the repl aren't actually saved for the next time you run your app? And how do you do testi…
So you can interactively change the code on Emacs, Cursive, CounterClockwise,... and then update the REPL state.
While using the REPL for debugging purposes.
So at the end of the coding session, all source files have the current state of the application.
Re: Fun vs. Computer Science (2016)
#127Earlier quoted context omitted.
This has not been my experience with strongly and statically typed systems. The biggest problem is the coding is not fast; especially if you make a change that requires "shaking the tree". Turnaround to me is as much about the code you write as it is the results you get from that code. For example, I start my program thinking that I need a duck for all of my various waterfowl systems. However, four days into the codi…
Nowadays I feel that experience with some type system at least as powerful as Haskell's is required to criticize static typing... Well, of course, you can criticize it without such experience, but that only serves to look foolish when you complain about stuff that is solved for a decade. Are you really complaining about lack of generics?
Re: Fun vs. Computer Science (2016)
#128Agree whole heartedly! That's why my favorite language is Clojure. That interactivity, instant feedback, seeing the program running as you are tweeking it, its a bliss to use and it creates better more functional software. Imagine playing music as you hear it when trying to come up with a good melody. Now imagine not playing it, but composing it on music sheets instead, and occasionaly playing what you've got every 1…
When showing off Clojure the application is often molded while running by patching it via the repl. But what I don't understand is if you can actually develop real programs like that? Surely even in Clojure code there are lots of dependencies so you can't just change one place in isolation. And I also guess that changes done on the repl aren't actually saved for the next time you run your app? And how do you do testi…
Well yes, I do it daily at my work. We develop backend SOA enterprise services like that, it works great.
Surely even in Clojure code there are lots of dependencies so you can't just change one place in isolation.
Well, there still are a few, but very little compared to most other languages. That's because everything is immutable by default, and state is passed around instead of accessed globally most of the time. So you'd be surprised how often you can actually work in isolation. Achieving this was Clojure's number one design tenet. To have a language which promotes untangling dependencies as much as possible, that makes it easy to write simple untangled code.
The other thing to realize is that the program running is not an isolated one like when doing TDD. It is the full program, with all its dependencies, connected to the file system, your databases, etc. I don't mock anything, if I'm trying to write my DB query, I try it for real on a real database.
And I also guess that changes done on the repl aren't actually saved for the next time you run your app?
So, that's why Clojure has tight integration between your editor and the REPL. Or tight integration between code files and the REPL. You normally don't type code at the command line, in fact, the Clojure REPL has no UI or command line interface, it's a network repl which listens to messages over a port using a special protocol called nREPL. Each editor that support Clojure connect to it, and send the content of the buffer to it for you. So you're editing the file and saving it as you see fit, while also asking the editor to have the file or part of it as you edit be sent to the REPL. You can also edit the file, save it, and then have the repl watch file changes and auto-reload them as they change. That way can work even with editors that don't have Clojure support. There is a CLI you can use too, for when you want an ephemeral program. Some editor also build UIs for the REPl, allowing rich media to be printed instead, like an interactive graph.
And how do you do testing?
Well, you're always testing, as you code, in parallel. Since your code is running live as you edit, you see the impact of your change right away. You're expected to also write unit and integ tests, and you do that like in all other language. These are needed for regression testing, but you don't need tests to test something works, you'll be doing that as you code fron the REPL. You need tests to make sure someone in the future doesn't revert your functionality. I actually find these are much easier to write in Clojure, again because the language pushes you to write isolated easy to test code, but also because you don't need a test framework and a mocking library, the core language is enough offers both.
How is the actual work flow you use when molding your app?
First I create a project. Then I start a repl configured from that project, then I open my editor and connect to my repl.
Then I write my main function and load it in the repl. I add more and more functions, loading them and trying them out as I do. Once I've got enough, I orchestrate calls to them from my main method, loading and reloading it all as I go, seeing the result of every step in the REPL. When I'm satisfied, I save my file. Once I've got what I want, i create a test file, write some regression tests, and then git commit, send a CR request, and then git push. Rince and repeat.
Re: Fun vs. Computer Science (2016)
#129Earlier quoted context omitted.
Well... but usually those are actual errors that you would need to fix anyway.
Why would generalizing a type definition make an error?
Re: Fun vs. Computer Science (2016)
#130Earlier quoted context omitted.
What you are saying is like the people that would "rather write new functionality than tests"... Like, yeah, that would be nice, if you were able to write 100% bug free code, but you aren't so your tests are actually important in the goal towards a working product.
Well, I'd actually rather write unit tests than shake out type trees too, so no, the two statements aren't equivalent. Why? Unit tests also check a lot more than the types being passed around, so they are a lot more useful in the long run. There are some type systems where this is perhaps not the case, but they certainly aren't the majority. The majority is "so do I go with a float or a double" or "I have to cast thi…