Re: [ClojureScript] Extending protocol to an existing JavaScript type
Thanks- that worked perfectly. I did not need to extend IFn and I actually got a runtime error when I tried (perhaps because IFn is a protocol in ClojureScript?). What are "function"/"object"/ect. in this case, syntactically? Is there any documentation about this? Thanks again! -Scott -- Note that posts from new members are moderated - please be patient with your first post. --- You received this message because you are subscribed to the Google Groups "ClojureScript" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojurescript+unsubscr...@googlegroups.com. To post to this group, send email to clojurescript@googlegroups.com. Visit this group at http://groups.google.com/group/clojurescript.
Re: [ClojureScript] Extending protocol to an existing JavaScript type
Extending a protocol to one of the global JS objects is bad for the same reason it is bad in Javascript: you are modifying a global object. Your extend-protocol is like saying Function.prototype.FOO_foo = function(this, arg){...} in javascript. (The "FOO_foo" is a long namespaced and mangled property name, but you are still modifying the global.) You can extend "function" (and "object", "number", "string", "array", and "boolean") instead of js/Function (or js/Object, etc). This will implement the protocol from the "outside" (doing type checks on its argument) instead of assigning a new member to the global's prototype. E.g.: (extend-protocol Foo function (foo [this] (println this))) I'm not sure if you also need to extend IFn: I think "function" means only native js functions and not clojurescript objects implementing IFn. (Test with a multi-arity cljs function to verify.) You can also extend the "default" type, which means everything will implement the protocol that doesn't have a more specific implementation. I don't know where these magic protocol type names are documented. On Thursday, September 3, 2015 at 6:58:48 AM UTC-5, Scott Nelson wrote: > (defprotocol Foo > (foo [arg])) > > (extend-protocol Foo > js/Function > (foo [arg] > (println arg))) -- Note that posts from new members are moderated - please be patient with your first post. --- You received this message because you are subscribed to the Google Groups "ClojureScript" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojurescript+unsubscr...@googlegroups.com. To post to this group, send email to clojurescript@googlegroups.com. Visit this group at http://groups.google.com/group/clojurescript.
Re: [ClojureScript] Extending protocol to an existing JavaScript type
(defprotocol Foo (foo [arg])) (extend-protocol Foo js/Function (foo [arg] (println arg))) -- Note that posts from new members are moderated - please be patient with your first post. --- You received this message because you are subscribed to the Google Groups "ClojureScript" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojurescript+unsubscr...@googlegroups.com. To post to this group, send email to clojurescript@googlegroups.com. Visit this group at http://groups.google.com/group/clojurescript.
Re: [ClojureScript] Extending protocol to an existing JavaScript type
Coukd you please post the code that produces that warning? Ideally a minimal case. On Thursday, 3 September 2015, Scott Nelson wrote: > Why is this bad practice? I'm trying to extend a protocol to js/Function > and I get the following warning: > > WARNING: Extending an existing JavaScript type - use a different symbol > name instead of js/Function > > I'm trying to create a function that is polymorphic based on the input > type (could be a function, map or vector) and I thought protocols were the > best way to do that. Should I instead create a multimethod that dispatches > on (type arg)? > > Thanks! > > -Scott > > -- > Note that posts from new members are moderated - please be patient with > your first post. > --- > You received this message because you are subscribed to the Google Groups > "ClojureScript" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojurescript+unsubscr...@googlegroups.com . > To post to this group, send email to clojurescript@googlegroups.com > . > Visit this group at http://groups.google.com/group/clojurescript. > -- Note that posts from new members are moderated - please be patient with your first post. --- You received this message because you are subscribed to the Google Groups "ClojureScript" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojurescript+unsubscr...@googlegroups.com. To post to this group, send email to clojurescript@googlegroups.com. Visit this group at http://groups.google.com/group/clojurescript.
[ClojureScript] Extending protocol to an existing JavaScript type
Why is this bad practice? I'm trying to extend a protocol to js/Function and I get the following warning: WARNING: Extending an existing JavaScript type - use a different symbol name instead of js/Function I'm trying to create a function that is polymorphic based on the input type (could be a function, map or vector) and I thought protocols were the best way to do that. Should I instead create a multimethod that dispatches on (type arg)? Thanks! -Scott -- Note that posts from new members are moderated - please be patient with your first post. --- You received this message because you are subscribed to the Google Groups "ClojureScript" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojurescript+unsubscr...@googlegroups.com. To post to this group, send email to clojurescript@googlegroups.com. Visit this group at http://groups.google.com/group/clojurescript.
[ClojureScript] Re: Bug in :optimizations :advanced
This is not a bug as David said. To expand a little more about why this happens. String.prototype.startsWith is not part of ES3 or ES5. Only with ES6 will it become standard. The default language level for the closure compiler is ES3 which is why it doesn't know startsWith. You can check the default externs of the closure-compiler [1] and a quick search reveals all supported functions for each type. For String we have: ag String.prototype es5.js 44:String.prototype.trim = function() {}; 53:String.prototype.trimLeft = function() {}; 62:String.prototype.trimRight = function() {}; es6.js 257:String.prototype.repeat = function(count) {}; 280:String.prototype.codePointAt = function(index) {}; 288:String.prototype.normalize = function(opt_form) {}; 298:String.prototype.startsWith = function(searchString, opt_position) {}; 307:String.prototype.endsWith = function(searchString, opt_position) {}; 316:String.prototype.includes = function(searchString, opt_position) {}; es3.js 1565:String.prototype.anchor = function() {}; 1573:String.prototype.big = function() {}; 1581:String.prototype.blink = function() {}; 1589:String.prototype.bold = function() {}; 1600:String.prototype.charAt = function(index) {}; 1612:String.prototype.charCodeAt = function(opt_index) {}; 1623:String.prototype.concat = function(var_args) {}; 1631:String.prototype.fixed = function() {}; 1640:String.prototype.fontcolor = function(color) {}; 1649:String.prototype.fontsize = function(size) {}; 1663:String.prototype.indexOf = function(searchValue, opt_fromIndex) {}; 1671:String.prototype.italics = function() {}; 1685:String.prototype.lastIndexOf = function(searchValue, opt_fromIndex) {}; 1694:String.prototype.link = function(hrefAttribute) {}; 1709:String.prototype.localeCompare = function(compareString, locales, options) {}; 1722:String.prototype.match = function(regexp) {}; 1730:String.prototype.quote = function() {}; 1745:String.prototype.replace = function(regex, str, opt_flags) {}; 1756:String.prototype.search = function(regexp) {}; 1766:String.prototype.slice = function(begin, opt_end) {}; 1774:String.prototype.small = function() {}; 1784:String.prototype.split = function(opt_separator, opt_limit) {}; 1791:String.prototype.strike = function() {}; 1799:String.prototype.sub = function() {}; 1809:String.prototype.substr = function(start, opt_length) {}; 1819:String.prototype.substring = function(start, opt_end) {}; 1827:String.prototype.sup = function() {}; 1835:String.prototype.toLocaleUpperCase = function() {}; 1843:String.prototype.toLocaleLowerCase = function() {}; 1851:String.prototype.toLowerCase = function() {}; 1859:String.prototype.toUpperCase = function() {}; 1867:String.prototype.toSource = function() {}; 1875:String.prototype.toString = function() {}; 1882:String.prototype.valueOf; 1888:String.prototype.length; When in doubt, look at the externs. HTH, /thomas [1] https://github.com/google/closure-compiler/tree/master/externs On Wednesday, September 2, 2015 at 3:48:17 PM UTC+2, Felipe Gerard wrote: > This is a minimal project to show the issue, the code breaks when using > :advanced optimization, .startsWith breaks: > > cljs code: > ** > > (ns minimal.core) > > (let [elem (.getElementById js/document "app")] > (set! (.-innerHTML elem) (str "Hello Worls " (.startsWith "Hello" "H" > > ** > > project.clj: > ** > > (defproject minimal "0.1.0-SNAPSHOT" > :description "FIXME: write description" > :url "http://example.com/FIXME"; > :license {:name "Eclipse Public License" > :url "http://www.eclipse.org/legal/epl-v10.html"} > :dependencies [[org.clojure/clojure "1.7.0"] > [org.clojure/clojurescript "1.7.48"]] > > :plugins [[lein-cljsbuild "1.0.6"]] > > :source-paths ["src"] > > :cljsbuild {:builds [{:id "dev" > :source-paths ["src"] > :compiler {:output-to > "resources/public/js/components.js" >:output-dir "resources/public/js/out" >:main minimal.core >:asset-path "js/out" >:optimizations :none >:cache-analysis true >:source-map true >}} >{:id "prod" > :source-paths ["src"] > :compiler {:output-to > "resources/public/js/components.min.js" >:main minimal.core >:optimizations :advanced >:pretty-print false}}]} > ** > > index.html (this works with code not optimized) > > > > > > > >Test