Re: [ClojureScript] Extending protocol to an existing JavaScript type

2015-09-03 Thread Scott Nelson
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

2015-09-03 Thread Francis Avila
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

2015-09-03 Thread Scott Nelson
(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

2015-09-03 Thread Gary Verhaegen
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

2015-09-03 Thread Scott Nelson
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

2015-09-03 Thread Thomas Heller
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