Hacker News new | past | comments | ask | show | jobs | submit | prospero's comments login

The point is that an interface should help you to both ignore and understand the underlying implementation. I'm not sure I understand your point about data and transport, since most interfaces (e.g. names) don't touch the network. Are these just synonyms for interface and implementation?


I bring it up because the author was talking about network transparent APIs, where the developer doesn’t have to care about whether the call goes over the network. But of course this is not something you can actually afford to ignore. It’s quite a different concern from the data exchange that happens between application and API, however.


Yes, and that is used as an example for the general point: a network transparent API doesn’t help us understand the network when it inevitably fails.


I was on a project once that developed an IPC API based on remote procedure calls. The first thing they did was hide the RPCs, precisely for this reason. And the second thing they did was ditch the RPCs in favor of TCP/IP socket reads and writes, because once you hide them the RPCs don’t buy you anything but headaches. Bye bye DCE.


Hi, author here. I looked into that side of things, but CGAL only offers exact precision implementations for lines and circular arcs. The fact that Bézier curves are left as an exercise for the reader is further proof of the disconnect between computational geometry and modern computer graphics.


Fair point. At the same time the exact computation paradigm is proof that problems like these can be solved in a rigorous way if you start with the right foundation.

By the way thanks for writing the article, it was a refreshing read.


I'm curious; I've played with OpenSCAD a little, which uses CGAL, and found it to be painfully slow (with no particular point of comparison). Do you think you have a way to do similar CSG calculations faster, or at least trade speed for accuracy or something?


It's very plausible that these techniques could be used to fix the output of a CSG library that uses floating point math, but I'm not sure what the specifics would look like. If anyone has ideas in that vein, I'd be very interested to hear them.


I was thinking along the lines (based on skimming documentation) of CGAL using arbitrary precision integer based rationals, which are slow, and using floating point with the error correction might potentially be faster.

Unfortunately, it's probably way beyond my ability to delve in to it.


By forcing the GC to run in between tests, basically. The README for the benchmarking tool describes it in more detail: https://github.com/hugoduncan/criterium.


I tried to include these, but it wasn’t immediately obvious how to construct them from outside Scala without CanBuildFrom. If anyone wants to open a PR or even provide a few hints, I’d be happy to update the benchmarks.


Scala 2.13 greatly simplifies the external interface of the collections and no longer requires CanBuildFrom [1]. You may find them much easier to work with now.

[1] https://scala-lang.org/files/archive/api/2.13.0-M5/


Guava’s “immutable” collections are effectively read-only indices, and do not support efficient updates.


Clojure’s maps, sets, and vectors are all functions.


First public release of Arc came not long after Clojure.

Clojure is definitely better thought out as a language, and while Arc has some interesting ideas around web development, it also doesn't have a module system, so everything is just loaded into the same global namespace, which is pretty insane.


Keep in mind that Arc is the start of something with long-term goals; further, it's part of a lifecycle that didn't necessarily start with Arc but with the first Lisp. PG points to an early essay titled "The Hundred-Year Language" [1] as an indicator of where Arc is intended to go and some future outlooks that might inspire more evolution.

I don't know that any programming language can be everything it needs to be from the outset, but it certainly needs inherent featured supporting longevity, a framework that supports change and evolution, while still having a pleasing and useful function that can be taken advantage of immediately.

[1] http://www.paulgraham.com/hundred.html


Ah, that makes sense. The next main difference in my mind is ergonomic, but relies on this regularity: functional syntax for composition, negation, quoted application. There are also other syntax additions and in my experience they're well-chosen and go a long way.


It would be more correct to say that they can be coerced to a function with a special purposes (e.g. using a set as a function is an alias for checking whether an item exists).

To say they are functions would be incorrect. By the same logic, a keyword is would be a function.


They're callable as functions, i.e. they implement clojure.lang.IFn. So unless you want to shave hairs on what it means to say they're not "functions", they _are_ functions. Sets, vecs, maps, keywords, and IIRC symbols are all IFn

Oh and (#{1 2} 3) is equivalent to (get #{1 2} 3) not (contains? #{1 2} 3)


I think that it depends upon what you interpret it when you say “it’s a function”; it’s data as well. Which, now that I reconsider it, was kind of the point that the parent was trying to make, that they’re also very much unified.

So point taken.


I’d think a relaxed radix tree would be ideal.


In the first ten minutes of the talk, the SICP definition (which is taken from the Hoare paper) is examined and discarded as too limited.


No idea why this is here, but I'm the speaker and happy to answer any questions.


Ha. I was wondering the same thing. I have a somewhat unrelated question for you, though.

You've been using Clojure for a while. Do you still like it? If you were to start your current project(s) over today, would you still use Clojure?

Clojure is on a list of technologies my team is considering using instead of Ruby/Rails. Our goal is to move to a stack that discourages complecting, encourages what we consider to be good practice (immutability, function composition, explicit dependencies, etc), and which has reasonably good performance characteristics. Clojure seems to fit the bill, and has the added benefit of syntactic simplicity which I really like.

Lack of static typing is probably the biggest downside vs some of the other languages we are weighing.


Clojure is the language I'm most productive in. At the beginning of the year I quit my job to write a book about Clojure [1], do some consulting, and build a developer tool I've been talking about for a few years.

For the tool, I'm using a client/server model, and on the client side latency is a huge concern, so I'm using Java. Java is basically assembler for the JVM, and has extremely predictable performance characteristics. Where performance is a non-issue, or I only care about throughput, I'm using Clojure, because it's much more expressive. I think the tradeoffs of the two languages are very complementary, but also much less extreme than, say, Ruby and C.

I find the inertia of the core implementation of the language annoying, even if it's not a huge problem for most applications. Clojure's immutable data structures were world-class when the language was first released ten years ago, but there have been a number of papers which detail improved approaches since then. I've implemented most or all of them [2], but the chance of getting these back into Clojure is effectively nil. That doesn't affect me (I can just use my own data structures), but it does give me some concern as to where the language will be after another ten years.

[1] http://elementsofclojure.com/

[2] https://github.com/lacuna/bifurcan


A. Thanks for the response.

B. Interesting. I saw a recent article on high-performance immutable data-structures[1], and wondered what the odds of Clojure implementing them might be. Sounds like you think the odds are minuscule.

C. I've heard great things about your book, and it is on my reading list! Thanks for writing it.

D. Given your hesitancy about the future of Clojure, what is your opinion of a more future-proof stack that has similar properties to Clojure (functional, simple, data-oriented, etc)? I can't think of many. ReasonML is interesting, but immature and definitely more complex than Clojure. Elixir seems to be promising, but I don't like the language, and I don't like being constrained to doing everything the BEAM way-- JVM is nice for high-perf computing when needed... Anyway, I'd appreciate your thoughts!

[1] https://news.ycombinator.com/item?id=15005569


The chance of my implementation being folded into Clojure, as opposed to whatever Rich writes himself, is definitely tiny. But there's no telling when he might get around to it, so the best way to stay sane is to assume it will never happen.

Clojure occupies a really nice local maximum, and I don't think any other language is trying to compete for that niche. Since Clojure is just a Java library, it's relatively easy for you to extend or replace any part of it, so I don't think the future is a concern for anyone who enjoys the language and is motivated to use it.

Rather, I worry about the growth of the community, since that's largely predicated on the out-of-the-box experience. As an author and consultant who is focused on Clojure, that affects me far more than a company which builds its product using Clojure (assuming you're willing to hire people with an interest in FP and teach them the rest in their first month). I don't claim expertise in how to grow a community around a language, but it seems to be at best a part-time job for the people at Cognitect, which is not ideal.


I am seeing pretty healthy CLJS adoption, especially as NPM access becomes easier and easier. The things that are happening on the client side seem to be out front of the rest of the industry fairly consistently over the past few years. I think that bodes really well for the Clojure community overall.


> Elixir seems to be promising, but I don't like the language

Here is an interesting /r/clojure thread about Elixir vs Clojure: https://www.reddit.com/r/Clojure/comments/6wn6t5/new_clojuri...


What are your main issues with Elixir's syntax?


From recent discussions on the CHAMP stuff I was under the impression that once clojure equality semantics were matched the performance improvements were fairly minimal. This is why there isn't more urgency around updating the core data structures. Is that not how you see it?


You probably saw my response in that thread, where I said that the dramatic performance improvements in lookup speed reported by the CHAMP paper were mostly because they were comparing apples to oranges.

However, Clojure's equality semantics only really help in some niche situations (where you want to be able to use ints, floats, and bignums interchangeably, mostly), so making the equality semantics configurable would be a huge win for all sorts of applications.

Also, lookup is not the only performance win that CHAMP offers: https://github.com/lacuna/bifurcan/blob/master/doc/benchmark.... One thing the approach makes possible, which wasn't explored in the paper, is the ability to do union/difference/intersection operations structurally, rather than just iterating over each element in the set.

None of these improvements are so overwhelming that they take priority over everything else. Clojure's data structures are still really well made. Given how data-focused the language is, however, I think these improvements are more compelling than everything that's been added to the language in the last five years other than `clojure.spec`.


Not OP, but I've got 5 years experience writing a Clojure web app from scratch. It began as kind of as a knee-jerk reaction to using Rails for a few years. All the reasons you mentioned are reasons we chose Clojure to implement CleanCoders.com: it was a simpler language, immutability caused fewer weird bugs, the community favored transparency over Rails-esque magic, it was fast, and everything felt very composable since mostly it was just functions. Overall it was nicer than using Rails. But honestly I wouldn't say it was much different of an experience than using Sinatra or Express.js. We had to plug a lot of tools together, which was kind of the real benefit over Rails, but it also came with its own cost, namely that you have to plug everything together, even if they don't fit well together, and half the time you just had to write some things yourself that you would have gotten for free in Rails (for better or worse). These days I personally am just fine writing in modern JS. Destructuring, lambda syntax, and object literals almost make it a tie with Clojure's terse syntax. And in practice mutation isn't really something that happens too often now that people have mostly learned that you should generally prefer returning new objects.


These days I personally am just fine writing in modern JS. Destructuring, lambda syntax, and object literals almost make it a tie with Clojure's terse syntax.

So isn't there anything you wish you had or missed from Clojure? Not even the JVM?


With how many libs I've been able to find on NPM, I don't miss the libraries of the JVM really. Most (if not all) of them have been rewritten by now. And the speed and concurrency of the JVM itself is great when you want to scale vertically, but there are plenty of decent ways these days to scale horizontally instead. The only thing I kind of miss is REPL-driven development, but for the most part that's only really a crutch for Clojure's slow launch, and it's just as easy in Node to write some experimental code at the top of your main file with an early exit, auto-reloading it using nodemon, and outputting whatever you're trying to see. You lose the ability to have live objects, but 99% of the time that's a non-issue.


While you're here, I'd like to say thanks for Aleph and Manifold - they have been very reliable and powerful workhorses.


I'm glad you've found them useful.


The lookup performance gain is largely due to the CHAMP implementation using the default Java equality semantics, while Clojure's maps use Clojure's more expensive equality semantics. See https://github.com/lacuna/bifurcan/blob/master/doc/benchmark... for a more in depth illustration of this.

However, it is still a meaningful incremental improvement over Clojure's implementation for iteration and equality checks, among others.


Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: