Live data from Hacker News

Fun vs. Computer Science (2016)

prog21.dadgum.com

121–130 of 184 posts

Re: Fun vs. Computer Science (2016)

#121
post #29

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…

It's a pretty good treatment. I think the solving the root cause would be something like a constant time compiler, which I don't think is going to happen. You don't need to mock at all if you do DI and modularity well in Guice or Spring or something else (it can be the rare exception for a few libraries that use say private constructors). You can also write 3-5 line tests that will absolutely test everything in your program, and be able to debug it line by line in a debugger. So, I'm not sure I would agree with Rich Hickey on this. REPLs are no substitute for a good IDE and debugger running a series of declarative tests.

Re: Fun vs. Computer Science (2016)

#122

I 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…

Um, we have those languages NOW. We've had them for decades. You just need to use them:

https://www.haskell.org/

Re: Fun vs. Computer Science (2016)

#123
post #73

Earlier 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.

Why would generalizing a type definition make an error?

Re: Fun vs. Computer Science (2016)

#124
post #88

Earlier 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.

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 this int to an uint64 for this one function".

Re: Fun vs. Computer Science (2016)

#125
post #4

Earlier 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…

Clojure doesn't do the image-based persistence thing. You can ahead-of-time compile to Java byte code if you want, but that's probably closer to the .fasl files created by some Common Lisp implementations. No old bits of state floating around when you deploy a new server. Do occasionally miss the ability to save an image, but it doesn't seem to be the modern way (and would be a nightmare to implement well on top of the JVM).

Can easily add a REPL to any Clojure program though.

Re: Fun vs. Computer Science (2016)

#126
post #4
post #2

Agree 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…

You can do stuff like send current (line, function, file, ...) to the REPL from the editor.

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)

#127

Earlier 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?

Come back to me when the most used programming languages have a type system like Haskell's. Then we can talk about the benefits of static typing over dynamic typing. Until then, static typing is mostly "expected a HashMap, got a HashMap" or other pedantic stuff like that which is only really meaningful to the compiler.

Re: Fun vs. Computer Science (2016)

#128
post #4
post #2

Agree 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…

But what I don't understand is if you can actually develop real programs like that?

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)

#129
post #73

Earlier 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?

In the places you use a specific concrete type you presumably did so for a reason, and now need to think about how the type change affects it. The parts of your code that are generic should have been written to be generic, and the parts where the type can be inferred from the lower-level functions involved should have left the type to be inferred from the lower-level functions involved.

Re: Fun vs. Computer Science (2016)

#130
post #88

Earlier 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…

So use a good type system rather than a bad one. I mean if your point is "some popular type systems are so bad that they're worse than no type system at all" then I agree with you, but don't tar all type systems with that brush.
Post reply on HN