Fork me on GitHub

I'm not sure how hiring goes with Clojure, since I'm just an amateur and my day-to-day programming is JavaScript. But Scala -> Go isn't too weird if the goal is to write code all in one way. Go doesn't give you many options.


I think I have to disagree about the java aspect. I really think it is a tough language, not from a theoretical perspective. But somehow Java is a mix of it's anchestores like C and C++ and all that stuff that arose into popularity in the last 20 years. And it also gives you a lot of options to do things wrong in so many ways. Especially as they dont seem to be wrong until you come back 2 years and 5 other developers working on it later. Maintaing a java product can be really hard. That said I have no comparison to go, so, I don't know if they made it better for a reasonably large code size.


I think the lack of Go features is the point (like in the article): the more you add, the more you give people multiple ways of doing the same thing, which leads to code being harder to work on in large groups. Go is short. To the point. Make it work, the end. It ain't pretty. 😛


Sounds like the Titanice without the iceberg just arriving overseas 😄


@jaen: I found out how I could write the puzzle of yesterday without a StringBuilder:


inspired by the Clojure solutions that only create a string in the last step


@sveri: I dunno, what's so hard in Java itself? The only two hard-ish things I've noticed when I've read about Java are generic wildcards (cause variance) and classloaders. Rest is your standard single-inhertiance OO fare. I'm not too sure what is really hard about that in and of itself. But I think I can agree, that actually creating software in Java is not trivial - there are best coding practices not enforced by the language (the equals contract for example), there are multiple design patterns that solve a similar enough problem and so on. But I think that's more a problem with the OO paradigm in general (especially when you are statically typed, but not enough to be Haskell, so types are more of a crutch rather than help) and also architectural concerns than Java in particular.


As for go's lack of features, I think they are missing wrong features TBH. Generics, optional values instead of nulls, package management - are all features I that I would call essential.


@borkdude: looks pretty cool.


@jaen: Guess how many people in my office read Effective Jave or Concurrency in Practice? Everyone I ask is not even aware of it. And we are a Java only shop. Working for one of the largest IT business here in germany. Of course this differs, but regarding the fact that there are millions of Java developers I'd argue the majority does not care about these things, because you can get stuff done mostly without knowing about that.It's only later in the process that these things may fall onto your feet. But maybe they are gone then already...Or are technical leads now, or lead something different, or whatever...


Right. Programming C++ without knowing all the books from between Best Practices and Advanced headings on this list - - by heart is just asking for writing terrible C++. I can imagine it's similar with their Java counterparts, but nonetheless I wouldn't call Java as complex language as C++. And most of those things don't stem from the language as it is, but either from mutability or object orientation or some other more basic building block.


So while I don't really like Java (my least liked programming language I think; I like PHP less, but I don't consider it a programming language to be honest) I don't think it per se is at fault in what you describe.


Get mutability out - concurrency suddenly becomes easier. Get object orientation out, give first class function - suddenly a lot of design patterns are superfluous.


True and there you have clojure 😄


I don't consider Clojure a language either. It's a Java list processing library.


@borkdude: That could be a pitch for some companies ("Oh it's just Java ! Go ahead then")


Haha, it's just a jar file, no one will see it beneath the other millions of dependencies 😄


Yeah, you almost have Clojure. I still can't stop wishing for types, though. But I guess that's just me ; d


there are types, but not statically enforced


Nope, me too, this is the thing I miss most in clojure


@jaen I'm finding what you said about design patterns spot on as I move to FP from OO. They're basically workarounds for deficiences in the language itself. And interesting what you said about Effective Java and Concurrency in practice. The former I read in 2001 and latter in 2006 but yet still not widely known or read :O


> Java list processing library You could then go "Those weird parens? That's just a list processing DSL, carry on."


@bigkahuna: yeah, there was this article on /r/Clojure recently which touched just upon that -


Hickey should have called Clojure JLP. Then we could write .jlp files instead of .jsp files and everybody would be happy.


But yeah, design patterns are basically convergent solutions to certain problems given certain constraints. If your constraint is "object oriented language without higher order functions and multiple dispatch" you suddenly need to solve problems the language would have been solving for you otherwise.


That's not to say design patterns are useless, it's just that they will look different in a more powerful languages.


@borkdude: re: types - yeah, I know. I've meant static typechecking by that. I just have about zero confidence in my code if I don't have something yelling at me if I make a mistake.


@jaen: I'm using squiggly clojure, it's quite good in catching some errors about arity. But yeah, return types etc., you only know it by usage.


@jaen: I wrote some Scala this weekend. Despite the type safety my code didn't work at first try anyway and had to write some unit tests. It's the same in Clojure. If you're writing unit tests anyway, you can have a lot of confidence


@borkdude: For me types are not about making it work, but knowing what is inside that param and what does that function return. It enhances readability for me.


@sveri: that's a good point


But well, that's emacs. I cannot into emacs. Though Cursive also offers some red squiggly lines like arity. But yeah - I'm more concerned about other invariants. Typo a map keyword - something somewhere could blow up with NPE (hello Clojure string functions) or just do nothing. Misplace a paren - have something somewhere blow up with can't cast ISeq to IFn. Both are things that happened to me relatively frequently. It's gotten better, but I still don't really 100% trust the language.


And I freaking suck at writing test '


Ie. I can't at all.


Which might explain why I prefer mandatory types to a degree.


@jaen Writing tests is usually straightforward.


@jaen: and in Clojure it's often easier, because it's not difficult to mock something (with-redefs)


For me it was always an exercise in staring at the screen and ultimately giving up, because nothing was getting accomplished '


I am wishing for types too. Clojure makes it easier to write tests (immutability, pure functions...) but still.


I recently spoke with a team that used Scala. They had a project that contained every message that could be interchanged in the form of case classes. I thought that was pretty neat.


Because that's a form of documentation.


But that was Ruby. It probably is easier in Clojure, since most functions are pure or pure-ish, but it's still hard for me to get in the mindset.


Yeah, sure is documentation. Especially if patterns need to be exhaustive.


Then you can't miss a case.


@jaen: you could look at Prismatic Schema as well. It's kind of the thing that makes up for static types in Clojure (if you're not using core.typed)


core.typed is not mature enough and is only developed by one person (I think). Cognitect could adopt it and make it more mature, but there are no signs it's going to happen.


Oh, I'm using schema. Without it I would be banging my head on the desk way more often.


But it's run-time, not compile-time. But then again - I'm just building websites, not Mars probes or something.


Clojure will probably never have enforced type signatures. Because you can get away without them, it's a discipline thing. Like TypeScript vs JavaScript. TypeScript won't become the dominant form I believe.


or maybe Hickey will come up with some breaking stuff in Clojure 2 and surprise us all with a far better thing than static vs dynamic... 😛


Yeah, it won't have. It's too old for that - you already have not-really-typeable idioms common in the language.


Unless you would be willing to lose those, but I'm not sure people would react favourably to that.


I was trying screeps some time ago and had to write plain javascript. I cannot for the hell of life imagine why anyone would do that if there is typescript or other things for that. It was so painful


Not comparable to clojure in any way.


And also > discipline well, you've got me here. It's a thing I severely lack. So bondage & discipline compiler is partly for making up for that in my case.


Well my (admitedly poor) understanding is that with type inference you can get partial checking (I think core typed rejects the fault on untyped code at the boundary).


But my dream would be full clojure/clojurescript type checking (ie. change something in the front end and get a heads up if it is not coherent with the db types)


I think Opa was something like that, but for some reason it never caught on.


@nha: Schema can get you there now?


Define a schema once, use it on client and server


Oh alright did not know that. pretty cool !


@borkdude: schema lacks the heads up


But yes, I am defining my schema in .cljc files and use them on both sides


@jaen: opa ? was it a Clojure thing ?


But if it didn't catch on then well.


Although I think editor support for Schema could be possible to some extent? (defn f [p :- Person] ...) (f {:nametypo "Foo"}).... -> warning?


@jaen: ok I see. Maybe ceylon will replace it then 😛


Wasn't Ceylon just a beter Java or am I mixing-up languages?


Also I think clojure would not be where it is now, if it would come with it's own runtime. Running on the JVM and the CLR was a very good move from Rich.


@jaen: you might mean Kotlin


@jaen : I thought Scala was a better Java ^^


it's a more complex Java


Scala is better Java + worse Haskell = JVM C++


More or less.


Yeah, Kotlin is certainly marketed as such, but last time I took a look at Ceylon it certainly didn't feel all that much different. Maybe things have changed.


at least Kotlin compiles fast


Scala has a bigger community + ecosystem. Kotlin is fairly new


Erik Meijer has said that he writes Scala in the Kotlin subset


I think the ceylon type system is really advanced


(union types for instance, not sure if they exist in scala)


@nha: is union types the same as: List[Int \/ String] ?


@nha: If we're talking about things like compile-time query validation and such there's also ur - - but I don't think it does frontend.


@borkdude: I can't tell, really ^^


And that's about all I can remember at the moment.


Union types are Haskell's data Maybe a = Nothing | Just a.


Haskell is pretty neat when it comes to types. Frege might show some promise there on the JVM, but I haven't got a clue about its performance.


@jaen I thought those were just algebraic data types.


@jaen: Ah I came across this one already, but never played with it.


In Scala Option seems to achieve the same by having case classes inherit a trait.


that fact that we can mix those languages and still use all those good libraries from the JVM ❤️


More verbose for one, don't know enough Scala to know for sure if that's exactly equivalent, that's two.


I'd love to see a discussion panel with Rich Hickey, Martin Odersky and the guy from Frege: the functional future of the JVM


@borkdude: ADT is the umbrella term. A | B in Haskell (or A * B in MLs) is the sum type (also called disjoint union type). (A, B) is a product type (or I would guess any constructor).


I think.


@nha: I'm kind of sad Opa didn't catch on, it seemed really interesting. I'm curious what was the reason for that.


It's always curious why some languages prevail, while other perish.


Interesting question. I never heard of Opa before. Clearly it is not only technical merits. Maybe ease of insertion into the current landscape ? But a good question.


I find that interesting too. How did JavaScript become the most popular (well almost) language of our time? Go figure


(Also, what makes a language die ?)


Ruby caught on by Rails if I'm not mistaking


maybe there will be a time when Clojure catches on by some killer productivity app


One thing I noticed they did with Opa


Is they initially had it's own OCaml runtime and more ML-like syntax. They moved over to run on node.js and made syntax more JS-like (while still keeping type inference and such), but it didn't seem to have mattered.


Yeah, Ruby was basically unknown until Rails. Maybe Clojure will have it's killer framework at some point, just more awesome than Rails. Something like Events on clojurE maybe.


EoE, I like the sound of that ; d


I kind of like that syntax. Experimented with F# for a while, liked it.


ML-ish syntax (ML, F#, Haskell) is probably the syntax I like the most.


I appreciate what LISPs are trying to achieve with parens, but for me it makes the code look to dense sometimes. Not enough to put me off, but enough to not make me 100% satisfied with the syntax either.


I'm surprised Scala has no collection literals


Yeah, same here.


I was similarly surprised when that statically-typed-Clojure-ish language (Lux was it, I think) decided to not have array literals either.


One of nice things Clojure added to LISP syntax was more punctuation and avoid superfluous parens, makes it easier on the eyes.


and the nice EDN notation, it's good esthetics


Oh, found an example - (@list 1 2 3). Doesn't jump out as well as [1 2 3] ; /


@jaen so then what’s your goto language if clojure’s dynamism you do not like?


@tesseract: ha-ha... it's actually Clojure. I don't like some things about it, but then again what language is ever perfect? I would probably prefer to write Haskell, but I just can't invest all that learning time to be productive in it, while I just could get started writing sensible code in Clojure fairly easily.


@jaen: what’s your language background?


@tesseract: Depdends on how you look at it - since I was very young I've played around with Basic, Delphi and C/C++. But that was just playing around - I didn't start doing serious learning until the university, but at least gave me an understanding of basic concepts like conditionals, loops and functions. My first serious program was probably a calculator in C# with precedence and functions, I've wrote during the summer holiday before the university. University was Delphi, C/C++ and a semester of Java basics. But the most important thing is that a friend has shown me Haskell and Linux during my first year - and then I actually started exploring all the fringe languages - I've tried bits of Haskell, Scala, LISPs, Nemerle, Rust and such. My first work experience was Ruby - I've been doing it for 4 years. And since a year ago I've decided I want try doing functional programming professionally (it's hard here, since there's no functional jobs in Poland at all) and here I am doing more serious Clojure for about a year.


I think that about sums it up.


All in all - eclectic.


very good! I’ve done Ruby professionally and C++/Java in school


doing some clojure now


but haven’t really worked with Scala/Haskell beyond toy projects


Yeah, me neither. I can write algorithms in Haskell relatively easily, but how to structure a non-trivial program? That's beyond me.


I look forward to learning more. Clojure is great fun so far.


Yeah, it's pretty nice. I wish it weren't dynamic, but it makes getting into Clojure easier.


Dynamic languages on the whole are easier to pick up.


And functional programming, immutability and STM offset downsides of the dynamic nature quite considerably.


I think it would be a good language to get into programming if not for the errors.


Racket or Elm still have a considerable edge here.


If Clojure could have Elm-grade errors then mind=BLOWN.


@jaen: why would a dynamic language be easier to learn?


Because it pushes the errors down to the runtime. You may do something wrong and yet your program will work more or less as expected.


Whereas with a static language you wouldn't even get it to run.


It's probably part of why PHP is so successfull


You can strongarm your website into working


Even if you aren't all that good at programming.


That reminds me of the Scala coursera course: I tried to figure something out in Scala, but could not get it to run. Then I programmed it in Clojure, and then ported back to Scala haha.


Yeah, it's exactly this - with a static programming you need to invest more up front in order to be effective with it.


For some people that's just too big of an obstacle and they get discouraged.


At a school where I used to work they used Java as the entry language. I remember in the first few weeks the students had to deal with compiler errors (forgotten semicolon etc) before seeing something. Yes, that's not inviting.


With a dynamic language you don't get that.


That's why I think LISPs are good first languages - there's almost no syntax.


Now they switched to Python for the entry classes. I think that may be a good move.


It's certainly better than Java, though I myself I'm opposed to having OO in introductory languages.


Pigeonholes thinking way too much.


you can write your first programs in Python without any OO. It's about statements, algorithms, just the first steps


True, I don't deny that


And in that it is better at Java


But as soon as you get to non-trivial stuff that requires libraries - whoops, objects.


I think it's also a more fun way to learn programming. After that you can deal with static types, OO, etc.


I really liked books like SICP and How to Design Programs if we're talking about introduction to CS.


It focused on the algorithmic part without getting the reader down with syntactic or hardware details.


Yeah, it's really good material


And I think a C would be a good second language after that - "Headfirst C" is a surprisingly good book.


I never though I'd say that about "Headfirst Something"


And only after those basics I think learning OO would make sense.


So that the programmer only knows it's one solution to certain problems, not the solution to everything.


ah good, I might read it simple_smile


Yeah, it's a really good introduction to C. There are some things I would nitpick, but otherwise it's really solid and in line with how I think learning C makes sense.


I never understood why teachers think saying "a pointer is a thing that points to some other thing"


Is a good explanation of pointers.


Skipping the memory model, how a pointer is really just a number of the first byte of memory you are looking at, how C types are basically views on the memory (ie. the way you interpret bytes) and so on is really not a simplification worth making and does disservice to the learners.


It's just more confusing if you don't understand what underlies it.


When I explained pointers that way to people they would understand them better than based on non-explanations they had at the university.


But sorry, I'm ranting '


@jaen - Just to add to dynamic languages debate here (prolly a bit late) to give a little bit of a counter point to some of the static longing I sense here, dynamic languages where data is convenient and idiomatic way to model ones domain has a lovely decoupling effect where 2 parties sharing data need not link to one another or share a class library or some such. I also think clojure gets certain affordances regarding expressivity for being dynamic. I wonder whether transducers would have been formulated in a static language like haskell eventually? I use to be a big fan of static types in Haskell and later F#, but the more Clojure I do the less I miss them. I didn't enjoy the lack of types in javascript and python however, probably because of mutability + OO / class based information sharing. I wonder what your thoughts are on this?


@danstone: sure but static typing doesn't mean you can't decouple in that way either. And if you use something like protobuff/thrift/cap'n proto you both get typing and only need to share the protocol defintion, not the codebase. Well, depends on how you define transducers exactly. I don't think Clojure has any formal definition of those apart from "what Clojure transducing functions do", so it's hard to say what exactly is their specification. But I've seen various effort to type transducers, both statelessly and statefully. I don't really know enough about transducers ATM to offer any concrete thought on that subject though.


But I agree that dynamic typing gives Clojure some leeway and makes it easier to ramp up with it. And that lack of mutability and OO mitigates quite a bit of downsides being dynamic has (at least in my eyes).


It's a tension between getting things to just work the way I want and architecting things to work the way I want, I think.


Clojure, LISP and dynamicity lends itself well to the evolution part of the spectrum; Haskell, F#, Scala, static typing lends itself better to giving more up front thought about what you implement.


I think the latter is objectively better, but in some settings it might be just too much effort for too little gain - like for example in webdevelopment.


And that's probably why dynamic languages are so popular with the webdev crowd - you don't need to be correct, you need to appear okay to the end user.


And then who wants to spend long months learning a ladder of abstraction Haskell has in order to just get people to pay them for a plan or their website.