4 ms·
What's wrong with: (deftype Foo SomeCommonProtocol (aMethod [blah blah] ...)) (+clj (extend-type Foo JvmOnlyInterface (
by wooby 12y ago
What's wrong with:
(deftype Foo
SomeCommonProtocol
(aMethod [blah blah] ...))
(+clj
(extend-type Foo
JvmOnlyInterface
(someMethod [blah] ...)))
Can you come up with another example you consider intractable?
- swannodette 12y agoThat's not equivalent to inline protocol implementation in both Clojure or ClojureScript. The point still stands, the proposal runs afoul of macro composition issues. This isn't to pass judgement on the proposal, but this is a tradeoff that is downplayed.
- brandonbloom 12y agoYour change is invalid. I picked my example very carefully: You can not extend an interface to an object after the type has been created. That only works with protocols. That said, there are countless examples. I already mentioned the proposed ns+ form, but there are a couple more in the design spec here: http://dev.clojure.org/display/design/Feature+Expressions http://dev.clojure.org/display/design/Feature+Expressions I'm not going to bother constructing more concrete examples, since it's trivial to do and each and everyone will have case-specific solutions that will seem "nicer" than feature expressions. But that's just it: It will be a case-by-case solution, rather than a general solution. Case-by-case application-centric solutions are preferable for the platform abstractions of your major subsystems, but often you just want to hack it and feature-macros simply don't offer the flexibility you need.
- wooby 12y agoAh, point taken. Here is a valid version: (case-host :clj (deftype Foo [] JvmOnlyInterface (aMethod [blah blah] ...)) :cljs (deftype Foo [])) (extend-type Foo SomeCommonProtocol (someMethod [blah] ...)) It is true there are countless examples. There are also countless counter-examples. And for the examples that are competitive in terseness, there is already cljx. I personally don't "just want to hack it", especially when it comes to writing portable code. I agree that portability poses subtle new challenges to application design. I just prefer to meet those challenges in a way that is programmable, which syntactic extension is definitely not.
- brandonbloom 12y agoLet me rephrase "just hack it": Feature expressions are a low-level primitive for platform switching. If you have cross platform abstractions, consumers of your code shouldn't need to use feature expressions. However, they are very useful in the implementation of such abstractions. As for the programability complaint: I just don't see why it is important. If you are generating code, you can already add/remove content from the generated code. That is: you can always just write a "feature macro"! Feature expressions don't add any power you don't already have: Only affordances for humans. Unrelated thought: Haskell/GHC uses the C preprocessor to address this problem.
- wooby 12y agoI agree that Feature Expressions don't add power, because yes, they are semantically equivalent to C preprocessing and orthogonal to the idea of Lisp. What excites us most about Feature Macros is that they do add power. Here is an example of something we think is powerful from the proposal - a cross-platform macro: (case-host :cljs nil :clj (defmacro my-macro [name & body] (case-target :clj `(.println (System/-out) (str (do ~@body))) :cljs `(.log js/console (str (do ~@body))))))
- brandonbloom 12y ago1) I don't understand what this example is supposed to demonstrate. 2) By "power" I meant a formal notion of expressiveness: Neither feature expressions nor feature macros add anything to the language that you can't already express with existing constructs. Like I said: It's about affordances, not capability.
- michaniskin 12y agoThe example demonstrates how you can define a macro that runs its code in Clojure but can emit code to both Clojure and ClojureScript. How would you do this with feature expressions?