Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It feels strangely.. nice.

I was always turned off by Python syntax, but liked the explicitness of Python code. I always liked LISP “syntax” but never learned any LISPs, and Clojure is really dense/implicit IMO. So Hy has a nice and unexpected balance of explicitness/familiarity and aesthetics.

But I wonder why someone would prefer this, aside from aesthetics. Macros?



Can you give an example of where you find Clojure to be implicit?

I don't find the Clojure that I write to be implicit.


Clojure(Script) reads Rubyish to me in the sense that I can't read the code until I understand every primitive. Contrast this with Python which almost reads like a natural language (which I don't say is better, but more explicit IMO).

    (defn widget-c [data owner]
      (reify
        om/InitState
        (init-state [_]
          {:message nil})
        om/IDidMount
        (did-mount [_]
          (let [events (sub (:notif-chan (om/get-shared owner)) :hello (chan))]
            (go
              (loop [e (<! events)]
                (om/set-state! owner :message (:data e))
                (recur (<! events)))))))
        om/IRenderState
        (render-state [_ {:keys [message]}]
          (if message
            (dom/p nil message)
            (dom/p nil "Waiting ... waiting ... waiting ..."))))


There is nothing implicit about that. You are instantiating an anonymous class (that's the reify) implementing 3 interfaces (presumably you looked these up since they're user libraries) that you are defining inline.

Compare this to something like a Django Rest Framework:

    class SnippetList(APIView):
        """
        List all snippets, or create a new snippet.
        """
        def get(self, request, format=None):
            snippets = Snippet.objects.all()
            serializer = SnippetSerializer(snippets, many=True)
            return Response(serializer.data)

        def post(self, request, format=None):
            serializer = SnippetSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
reify doesn't require any special knowledge that class doesn't. The Python code here is subclassing a single abstract class (APIView) instead of 3, but it has the same "problem" in that you have to know what methods to override. Again this is user code so you probably looked up what APIView needs to work just like you looked up with InitState, IDidMount, and IRenderState.

reify vs class in Clojure vs Python is a matter of idioms. You can definitely create an actual class instead of reifying in clojure, it just isn't necessary. Likewise, you could create an anonymous type in python via type(), but you'd probably get fired and/or shot in most circles for doing so.


I mostly wasn't talking about the high-level structure. Compare these methods:

        serializer = SnippetSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
with this:

        (let [events (sub (:notif-chan (om/get-shared owner)) :hello (chan))]
            (go
              (loop [e (<! events)]
                (om/set-state! owner :message (:data e))
                (recur (<! events)))))))
In order to have a remote idea what's going on, I need to know about channels, what `events`, `sub`, `go`, `loop`, `recur`, `<!` are. In Python, it's easy to tell syntax and primitives from library classes and methods, but here I'm not sure which is which. That's what I mean by Clojure being dense. Of course it's stupid to assume you read the source without understanding the language first, but “Python after you know some OOP“ is still easier to read for absolute language beginner than “Clojure if you know some FP”. Again, I don't imply that Python is somehow better because of that.


What about Clojure seems dense or implicit to you? Clojure and Python have a similar feel to me. Both are well-designed in the sense they strive for a small set of primitives useful in solving a broad range of problems.


See my reply to your sibling. I appreciate it may be very well designed; just saying there's a barrier for a novice to read it (which is fine, but different from Python). Even if you come from a different background (JS, C#), it's trivial to understand Python code because it reads like English. Both Clojure and Ruby are different because they're more dense (but as a result, probably more expressive). And I'm saying this as someone who doesn't really enjoy Python because it's way too sparse. Oh well, whatever :-). I should go learn some Clojure.




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

Search: