Hacker Newsnew | past | comments | ask | show | jobs | submit | ajss's commentslogin

> The function `a -> Maybe a` is a different function than `a -> a`. Despite his intuition that the latter provides a stronger guarantee and shouldn't break code, callers may be expecting the Functor instance that the `Maybe` provides and therefore is a breaking change.

I don't really follow that. How can it be a breaking change? Can you give an example?


If you're building a parser, you may use: http://hackage.haskell.org/package/parsec-3.1.13.0/docs/Text...

Where your downstream parsers match on `Nothing` and assume the stream hasn't been consumed in order to try an alternative parser or provide a default.

If you change an equation to use `option` instead you have a completely different parser with different semantics.

I was thinking of a case where I use your function in a combinator that depends on the Functor and Monoid instances provided by the `Maybe` type. If you change your function to return only the `a` and it doesn't provide those instances then you've changed the contract and have broken my code. And I suspect it should be easy to prove the equations are not equivalent.


I really dislike that.

The document is mutable and goes through a whole sequence of states that aren't what you want?

Constructing a body object with a document argument modifies the document?


People were running a real money service that consumed JSON from another service and it didn't validate the incoming JSON? Wow.


The problem comes from the fact that clojure and clojurescript are two different type disciplines, but people approach them with the same expectations. That exact problem would have errored out if they were running clojure, and a thrown exception is good enough validation for many developers. But because they were duped into a false safety net by thinking clojure == clojurescript, it slipped right underneath their radar.


Along a similar line, I love Stuart Halloway's talk on Narcissistic Design - https://www.youtube.com/watch?v=LEZv-kQUSi4

Prefer APIs over data.

Start with DSLs.

Always connect (and never enqueue).

Create abstractions for information.

Use static typing across subsystem boundaries.

Put language semantics on the wire.

Write lots of unit tests.

Leverage context.

Update information in place.


Specs are not scoped. There's a global registry. You may end up chasing other people's bugs.


I think "late indexing" maybe referring to an implementation detail. The indexes aren't updated after each transaction. When you query the db, the result is a merge between the index and the transactions that haven't been indexed yet. The index is updated in batches.


Look at the function doc string. Look at the function spec/fdef Look at the function comments.

OK, there aren't any. Pull requests accepted?


(defn [o n] (.write o n)) will have to look up the .write method by doing reflection on o & n at runtime, which is really slow.

(defn [^WriteInterface o ^long n] (.write o n)) can be much faster because the compiler knows the type of o & n.


I think you meant to say, (defn func[o n] (.write ^WriteInterface o ^long n))

This is needed only when calling Java methods, because Java allows overloading. Clojure only does arity-overloading, not type overloading, and hence doesn't need the type info.


Emacs for Swift, Objective C, C, C++, Clojure, Python, Java, Javascript, Assembler, Bash, and random other minor stuff.

Wait... there are other IDEs?


Ayn Rand didn't use force to take anyone's money. That's what she hated. When those who took her money offered her a small portion back, her philosophy didn't require her to refuse it.

Like if she was in a forced labour concentration camp, her philosophy wouldn't require her to refuse to eat the food she was offered.


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

Search: