Live data from Hacker News

Dueling Rhetoric of Clojure and Haskell

tech.frontrowed.com

101–107 of 107 posts

Re: Dueling Rhetoric of Clojure and Haskell

#101
post #100

Earlier quoted context omitted.

EDN is much more like XML than it is JSON. 1) When I read #uri " http://google.com" my app code sees (java.net.URI. " http://google.com" ), not Tag "URI" " http://google.com" or whatever. clojure.core/map does not see tagged values, it does not know that the values were ever read from edn. 2) Extension happens in userland library code, you don't need to go modify the hardcoded pattern match in core. (Talking about re…

I think it would be a great service if someone would write up a technical introduction to this for non-Clojurists. You seem to be communicating a subtle point that not many of us are getting ...

Just wrote this in r/clojure hth https://www.reddit.com/r/Clojure/comments/7a4qxp/dueling_rhe...

RH already gave a great nontechnical introduction in the EDN talk in 2012, I linked you a transcription of it upthread

Re: Dueling Rhetoric of Clojure and Haskell

#102
post #94

Earlier quoted context omitted.

(require '[foo :refer [f]]) ; edit f in foo.clj (require '[foo :reload]) (f 1) ; should call NEW f. Node doesn’t have a reload construct. If you hack it in by mucking with the module cache, you still won’t get the new f in your module’s local copy of it.

But doesn't the same apply for integer too, as in my example? After reloading y should refer to the NEW x? And what should happen in your example if f were deleted?

If f were deleted, it would still be in memory unless you explicitly call ns-remove to clean it up. In practice, this is rarely an issue, but I do wish the experience was a little cleaner there.

The same things do apply to integers, but if you use them at the top level (outside a function) then they will be dereferenced immediately (there is no delayed function body to wait for) and so you will get the initial value only once. If you want to enforce a delay, you can use (var x) or the shorthand #’x and later derefence that with @

Re: Dueling Rhetoric of Clojure and Haskell

#103
post #98
post #97

Earlier quoted context omitted.

Well, the three key aspects, in my preference order, are: 1. Server repl with editor integrated clients. So your text buffers in your favorite editor is the repl. Look at the gifs here https://atom.io/packages/proto-repl to give you an idea for it. 2. Reifed language constructs. You can read about it here http://www.lispcast.com/reification . An easy example is if you have fn A depend on B. If you change B and call A…

Thanks, that's very helpful. As a Haskell programmer I already know the benefits of 3! 1 and 2 are things that I don't take advantage of so I have a couple more questions. 1. Is this like a Jupyter notebook or some different sort of functionality? 2. Does it work for integer values, say, as well as functions? Suppose my source code says x = 1 and in my REPL I write y = 10 + x and then I change my source code to x = 2…

Is this like a Jupyter notebook or some different sort of functionality?

Its similar in some ways, but not quite exactly the same thing. The repl is a server, and doesn't have an interface. So it reads over a socket port, and prints a response back over the socket using a common protocol. So you can build any client you want for it. What is most common is to take an existing editor, like emacs, vim, eclipse, atom, etc. And write a plugin for them which interacts with the server repl. So say your in eclipse, you have a Clojure project open, you can have eclipse send your project code to the repl for you. In practice that means you just work on your code files directly, and just sync them to the repl as you go. Some clients try to be even fancier, creating visual representation of code output like graphs, or gui controls like drilling into a nested map.

Does it work for integer values, say, as well as functions? Suppose my source code says

Y would be 12.

(let [x 1 y (+ 10 x)] y)

If you load this it'll return 11. If you change x to 2 and reload this, it will return 12.

Globally you'd do:

(def x 1) (def y (+ 10 x)

Now y is equal to 11. If you change x to 2, and only reload x, y would still be equal to 11. You'd have to reload y also if you want it to be 12 now.

That's because y is bound to the value of the expression, not to the expression itself. And the value is calculated at load time.

Now you could bind it to the expression by using a function.

(def x 1) (def y #(+ 10 x)

#() is Clojure's shorthand for lambda.

So now the caller is in charge of deciding when to evaluate y.

Calling: (y)

Would return 11 and if you change x to 2, calling it again would return 12.

You can also use reactive constructs instead. So when setting x to 2, an event is published, so you can listen to it and have it reset y to the new value of evaluating (+ 10 x).

Re: Dueling Rhetoric of Clojure and Haskell

#104
post #57

Watching Hickey's talk, many of the complaints seemed to be valuable, but they didnt seem to be about static types . Rather, it was about some problems with existing data types locking one into a rigid data model when the domain is constantly expanding. This post by DeGoes makes the same point. http://degoes.net/articles/kill-data The default model of algebraic data types is too inflexible. There are different extens…

I wonder if there's an at-least type system so one could say it needs Person (n,a,c) and if it gets a Person (n,a,c,h) well that's consider a superset and thus accepted.

Re: Dueling Rhetoric of Clojure and Haskell

#105
post #57

Watching Hickey's talk, many of the complaints seemed to be valuable, but they didnt seem to be about static types . Rather, it was about some problems with existing data types locking one into a rigid data model when the domain is constantly expanding. This post by DeGoes makes the same point. http://degoes.net/articles/kill-data The default model of algebraic data types is too inflexible. There are different extens…

I wonder if there's an at-least type system so one could say it needs Person (n,a,c) and if it gets a Person (n,a,c,h) well that's consider a superset and thus accepted.

Sure, flow/typescript already do this by default.

Re: Dueling Rhetoric of Clojure and Haskell

#106
post #5

I wanted to like Haskell, but just never could get to the point where I enjoyed using it. It always felt messy and complicated to me. I think the language extensions were a contributor to these feelings. I also felt as if I spent more time wrangling with the type system than actually solving my business problems. Yet I really do like Clojure, F#, and PureScript. There's an experimental C++ back-end to PureScript now…

I also really dislike this extension system where you can unlock some magical features if you could just know what magical keyword to put at the top of your file.

The language was designed as a testbed for future PL research. That was the primary goal.

Re: Dueling Rhetoric of Clojure and Haskell

#107
post #72
post #56

Earlier quoted context omitted.

I tend to ignore 99% of the clever haskell stuff and get by just fine in Haskell. I keep learning about stuff like GADTs and whatnot, but they're more like the top of the tool drawer special tools than the ones you break out every day. I think people learning/using haskell tend to go for crazy generalized code first, versus what gets me to a minimal working thing that I can expand/change out later. Or I just suck at…

> Or I just suck at haskell You suck at Haskell about as much as Don Stewart :) In this talk he describes how he builds large software systems in Haskell and eschews complicated type system features https://skillsmatter.com/skillscasts/9098-haskell-in-the-lar...

Good to know i'm in good company then. :)
Post reply on HN