Re: ArithmeticException from unchecked-add

2014-05-20 Thread Greg D
Thanks. I've got to pay more attention to the distinction between long and 
Long in the documentation.

The docs for unchecked-add (
 http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/unchecked-add
 ) 
 only cover the case of both arguments being primitive longs. 



-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Joy of Clojure example not working

2014-05-20 Thread Greg D
Yes, the examples in the book are missing some lines. I think the following 
log shows what they were going for:

joy.udp= (remove-method compiler ::osx)
joy.udp= (def unix (into unix {::c-compiler /usr/bin/gcc}))
joy.udp= (def osx (into osx {:c-compiler gcc}))
oy.udp= osx
{:home /Users, :llvm-compiler clang, :os :joy.udp/osx, 
:joy.udp/prototype {:home /home, :os :joy.udp/unix, :c-compiler cc, 
:dev /dev}, :c-compiler gcc}
joy.udp= unix
{:home /home, :joy.udp/c-compiler /usr/bin/gcc, :os :joy.udp/unix, 
:c-compiler cc, :dev /dev}
joy.udp= (compiler osx)
gcc
joy.udp= (compile-cmd osx)
/usr/bin/gcc

About your question:

 Isn't there a core function/macro where I can derive and set hierarchy all 
 at once?

Such a function would need to know in advance what hierarchy you want to 
construct. If you have a desired pattern of hierarchy that you want to 
reuse, you could define a function to create it using derive and 
optionally make-hierarchy. 


On Monday, May 19, 2014 4:38:00 PM UTC-7, gamma235 wrote:

 I actually just wanna know why I need to use derive so many times. Isn't 
 there a core function/macro where I can derive and set hierarchy all at 
 once? I'm just looking for a more efficient way. My bad for not stating 
 that more clearly in the original post. 

 The real problem though is the last two calls to compile-cmd. I've been 
 messing with it for a couple of days so any help there would be well 
 appreciated.

 Thanks

 J



-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Joy of Clojure example not working

2014-05-19 Thread Greg D
The second edition of Joy of Clojure, MEAP v10 shows the same error and 
progressive solution about half way down pdf-page 318 in section 9.2.4.

On Monday, May 19, 2014 6:39:26 AM UTC-7, gamma235 wrote:

 Hi guys, I am working through the pre-release second edition of Joy of 
 Clojure's section on multi-methods (section 9.2.~ : pg. 313), and am 
 getting different outputs from what they have printed in the book. I could 
 just skip over it, but I really want to understand this stuff. Could 
 someone tell me how to get the *(compile-cmd osx) *call at the end of the 
 code to produce the expected output:  */usr/bin/gcc *? I have commented 
 out redundancy and moved a couple of lines for readability. Thanks in 
 advance! 

 J

 (ns joy.udp
   (:refer-clojure :exclude [get]))

 (defn beget [this proto]
   (assoc this ::prototype proto))

 (defn get [m k]
   (when m
 (if-let [[_ v] (find m k)]
   v
   (recur (::prototype m) k

 (def put assoc)

 ;;; compiler
 (defmulti compiler :os)
 (defmethod compiler ::unix [m] (get m :c-compiler))
 (defmethod compiler ::osx [m] (get m :llvm-compiler))

 (def clone (partial beget {}))

  

 (def unix {:os ::unix, :c-compiler cc, :home /home, :dev /dev})

  

 (def osx (- (clone unix)
  (put :os ::osx)
  (put :llvm-compiler clang)
  (put :home /Users)))

 ;;; home
 (defmulti home :os)
 (defmethod home ::unix [m] (get m :home))
 (defmethod home ::bsd [m] /home)

  

 ;; the error on the call to (home osx) is contingent upon toggling the 
 following lines. 

 ;(derive ::osx ::unix)
 ;(derive ::osx ::bsd)
 (prefer-method home ::unix ::bsd)
 ;(remove-method home ::bsd)   
 (derive (make-hierarchy) ::osx ::unix) 

 ;;; compile-cmd
 (defmulti compile-cmd (juxt :os compiler))

 (defmethod compile-cmd [::osx gcc] [m]
   (str /usr/bin/ (get m :c-compiler)))

 (defmethod compile-cmd :default [m]
   (str Unsure where to locate  (get m :c-compiler)))
 ;;

 (home osx) 

 ;= java.lang.IllegalArgumentException: No method in multimethod 'home' 
 for dispatch value: :joy.udp/osx …

  ;; Should be: ;= /Users


 (compile-cmd osx)

 ;= Unsure where to locate cc 

  ;; Should be: ;= /usr/bin/gcc

  

 (compile-cmd unix)

 ;= Unsure where to locate cc

 ;; this is the expected output 



-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Best way to pass parameters?

2014-05-19 Thread Greg D
Not an answer to your question, but you may want to check out:
Datomic: The fully transactional, cloud-ready, immutable 
database.http://www.datomic.com/

On Monday, May 19, 2014 10:07:15 AM UTC-7, Ivan Schuetz wrote:

 Hi,

 I'm building a webservice, have 2 layers: webservice and database.

 Webservice layer receives e.g. a product, to add to the database:

 {:id 1 :name phone :price 100}

 Database layer has a method to insert the product, insert-product.

 I could do 1):

 (defn insert-product [params])

 or 2):

 (defn insert-product [id name price])

 or 3):

 (defn insert-product [{:keys [id name price]})


 I tend to prefer 2) because it's safer than 1) and will allow me to add 
 type check later, don't think this is possible with 3). It doesn't feel 
 very idiomatic though and makes me feel like I might be thinking in 
 Java...


 I also want make possible to change the keys before inserting in the 
 database, where 2) and 3) are better than 1).


 Is 2) the best option? Is there any reason to use 3) instead? Or is there 
 maybe a different, better way?



 Thanks!


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


ArithmeticException from unchecked-add

2014-05-19 Thread Greg D
I didn't expect this one.  See the illustrative sequence below.

Should I be reporting this as a bug, or re-read the docs?

; CIDER 0.5.0 (Clojure 1.6.0, nREPL 0.2.3)

user (require '[clojure.stacktrace :as st])

user (unchecked-add (Long/MAX_VALUE) (Long/MAX_VALUE) )
-2

user (unchecked-add ^long(Long/MAX_VALUE) ^long(Long/MAX_VALUE) )
-2

user (unchecked-add ^Long(Long/MAX_VALUE) ^Long(Long/MAX_VALUE) )
ArithmeticException integer overflow  clojure.lang.Numbers.throwIntOverflow 
(Numbers.java:1424)

user (st/e)
java.lang.ArithmeticException: integer overflow
 at clojure.lang.Numbers.throwIntOverflow (Numbers.java:1424)
clojure.lang.Numbers.add (Numbers.java:1723)
clojure.lang.Numbers$LongOps.add (Numbers.java:447)
clojure.lang.Numbers.add (Numbers.java:126)
clojure.lang.Numbers.unchecked_add (Numbers.java:1671)
user$eval2514.invoke (form-init3948440390155694364.clj:1)
clojure.lang.Compiler.eval (Compiler.java:6703)
clojure.lang.Compiler.eval (Compiler.java:)
nil

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Improving pprint behavior for anonymous functions

2014-04-26 Thread Greg D
Simpler yet using metadata:
(ns example.ppfn)

(defn print-pf [pf]
  (if-let [ppf (::ppf (meta pf))] ppf pf))

(defmacro partial* [ args]
  `(let [m#  (pr-str '(partial* ~@args))
 pf# (with-meta (partial ~@args) {::ppf m#})]
 (defmethod print-method (class pf#) [o# w#] (print-simple 
(example.ppfn/print-pf o#) w#))
 pf#))

In use:
user= (def p1 (partial* + 1))
#'user/p1
user= (p1 5)
6
user= p1
(example.ppfn/partial* + 1)
user= (def comma-join (partial* clojure.string/join , ))
#'user/comma-join
user= (comma-join ['a 'b 'c])
a, b, c
user= comma-join
(example.ppfn/partial* clojure.string/join , )

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: puzzled by RuntimeException

2014-04-25 Thread Greg D
Thanks Alex and Steve,

I've based a ton of work on keywords where the second character is numeric.

The http://clojure.org/readers page should be the normative reference.


The work is based on *reliance* on the definitions in the readers page. I 
believe it is unambiguous in demanding a colon as the first character of a 
keyword, and allowing the second character to be numeric.

I am frightened that opinions differ; especially Rich's, obviously.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Improving pprint behavior for anonymous functions

2014-04-25 Thread Greg D
I don't know if this is considered good Clojure, but you could define a 
print-method within a macro to set up the normal string representation for 
the partial function:
(defmacro partial* [fname arg0  args]
  `(let [pf#  (partial ~fname ~arg0 ~@args)
 cpf# (class pf#)]
 (defmethod print-method cpf# [o# w#]
   (if (nil? '~args)
 (print-simple (str (partial  '~fname   (pr-str ~arg0) )) w#)
 (print-simple (str (partial  '~fname   (pr-str ~arg0) ~@(map 
#(str   (pr-str %)) args) )) w#)))
 pf#))

A transcript of some quick examples:
user= (def p6 (partial* + 1 2 3))
#'user/p6
user= p6
(partial + 1 2 3)
user= (p6 7)
13
user= (def re-find-foo (partial* re-find #foo))
#'user/re-find-foo
user= re-find-foo
(partial re-find #foo)
user= (re-find-foo abcdefooghi)
foo


On Friday, April 25, 2014 9:01:37 AM UTC-7, Matthew DeVore wrote:

 Hi,

 There has been one thing bugging me for a long time that seems worth it to 
 fix, and I was wondering if anyone else has had the same problem. I have 
 enjoyed using Clojure's REPL and embracing a Clojure-style data model for 
 my app, where everything is a glorified map or vector and there are no 
 private fields. I even have a simple dump feature that tells me the entire 
 state of my app https://github.com/google/hesokuri that was 
 ridiculously easy to implement, and that takes advantage of the lack of 
 black box data structures.

 One thing that doesn't really fit in this paradigm is (ironically) 
 anonymous functions with closures. For instance, (partial + 42) returns an 
 anonymous function, and in the REPL or an app dump, it looks hideous:
 #core$partial$fn__4228 clojure.core$partial$fn__4228@1ee1dea2

 So I've avoided anonymous functions in my app except when they exist 
 transiently, and don't appear in the dump (for instance, in (map #(str % 
 !) foo)). But sometimes I just can't avoid a long-lived anonymous 
 function practically. The best solution I've come up with is to transform 
 anonymous functions when preparing the application dump. (See the 
 implementationhttps://github.com/google/hesokuri/blob/b60cb7222cfdd672e394ef6f22b80c94278fe3a0/src/hesokuri/see.clj#L35)
  
 This makes (partial + 42) look like this:

 {:fn-class clojure.core$partial$fn__4228,
  arg1 42,
  f {:fn-class clojure.core$_PLUS_}}

 Which isn't great (I'd like to have filenames and line numbers for each 
 anon fn, and a nicer name for clojure.core/+), but it's a big improvement. 
 The function's JVM class and the closured values are revealed. It would be 
 nice to implement this natively. Having only passing familiarity with the 
 Clojure code base, to solve it I think one could:

- give anonymous functions a .getClosure method which creates a view 
of the closure on-demand
- (optional) change their .toString implementation to include this 
information
- add logic to clojure.pprint to use the .getClosure method (I guess 
(defmethod clojure.pprint/simple-dispatch clojure.lang.AFunction etc...) 
?)

 Another feature that would go nicely with this is smarter equality 
 semantics for anonymous functions, so that any two anonymous functions 
 generated at the same point in code with equal closures are equal. This 
 means if I have a function like this:

 (defn exclaimer [bangs] #(apply str % (repeat bangs !)))

 then the following would be true: (= (exclaimer 10) (exclaimer 10)), 
 making functions behave a lot more like values. I would love to have this 
 particular feature too, although I'm having trouble coming up with a 
 non-contrived example.

 I'd like to hear some thoughts on this. Thanks!

 Matt





-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Improving pprint behavior for anonymous functions

2014-04-25 Thread Greg D
I guess I don't understand the problem, or what is meant by different 
classes.  A counter-example would be helpful.

Further transcript using the macro:
(def p6 (partial* + 1 2 3))
#'user/p6
user= (class p6)
clojure.core$partial$fn__4194
user= (def p10 (partial* + 1 2 3 4))
#'user/p10
user= (class p10)
clojure.core$partial$fn__4196
user= p6
(partial + 1 2 3)
user= p10
(partial + 1 2 3 4)
user= (p6 100)
106
user= (p10 100)
110

On Friday, April 25, 2014 2:33:50 PM UTC-7, Gary Trakhman wrote:

 That's not going to work, all the return classes of partial are the same 
 class.


 On Fri, Apr 25, 2014 at 5:26 PM, Greg D gregoir...@gmail.comjavascript:
  wrote:

 I don't know if this is considered good Clojure, but you could define a 
 print-method within a macro to set up the normal string representation for 
 the partial function:
 (defmacro partial* [fname arg0  args]
   `(let [pf#  (partial ~fname ~arg0 ~@args)
  cpf# (class pf#)]
  (defmethod print-method cpf# [o# w#]
(if (nil? '~args)
  (print-simple (str (partial  '~fname   (pr-str ~arg0) )) 
 w#)
  (print-simple (str (partial  '~fname   (pr-str ~arg0) ~@(map 
 #(str   (pr-str %)) args) )) w#)))
  pf#))

 A transcript of some quick examples:
 user= (def p6 (partial* + 1 2 3))
 #'user/p6
 user= p6
 (partial + 1 2 3)
 user= (p6 7)
 13
 user= (def re-find-foo (partial* re-find #foo))
 #'user/re-find-foo
 user= re-find-foo
 (partial re-find #foo)
 user= (re-find-foo abcdefooghi)
 foo


 On Friday, April 25, 2014 9:01:37 AM UTC-7, Matthew DeVore wrote:

 Hi,

 There has been one thing bugging me for a long time that seems worth it 
 to fix, and I was wondering if anyone else has had the same problem. I have 
 enjoyed using Clojure's REPL and embracing a Clojure-style data model for 
 my app, where everything is a glorified map or vector and there are no 
 private fields. I even have a simple dump feature that tells me the entire 
 state of my app https://github.com/google/hesokuri that was 
 ridiculously easy to implement, and that takes advantage of the lack of 
 black box data structures.

 One thing that doesn't really fit in this paradigm is (ironically) 
 anonymous functions with closures. For instance, (partial + 42) returns an 
 anonymous function, and in the REPL or an app dump, it looks hideous:
 #core$partial$fn__4228 clojure.core$partial$fn__4228@1ee1dea2

 So I've avoided anonymous functions in my app except when they exist 
 transiently, and don't appear in the dump (for instance, in (map #(str % 
 !) foo)). But sometimes I just can't avoid a long-lived anonymous 
 function practically. The best solution I've come up with is to transform 
 anonymous functions when preparing the application dump. (See the 
 implementationhttps://github.com/google/hesokuri/blob/b60cb7222cfdd672e394ef6f22b80c94278fe3a0/src/hesokuri/see.clj#L35)
  
 This makes (partial + 42) look like this:

 {:fn-class clojure.core$partial$fn__4228,
  arg1 42,
  f {:fn-class clojure.core$_PLUS_}}

 Which isn't great (I'd like to have filenames and line numbers for each 
 anon fn, and a nicer name for clojure.core/+), but it's a big improvement. 
 The function's JVM class and the closured values are revealed. It would be 
 nice to implement this natively. Having only passing familiarity with the 
 Clojure code base, to solve it I think one could:

- give anonymous functions a .getClosure method which creates a view 
of the closure on-demand
- (optional) change their .toString implementation to include this 
information
- add logic to clojure.pprint to use the .getClosure method (I guess 
(defmethod clojure.pprint/simple-dispatch clojure.lang.AFunction 
 etc...) 
?) 

 Another feature that would go nicely with this is smarter equality 
 semantics for anonymous functions, so that any two anonymous functions 
 generated at the same point in code with equal closures are equal. This 
 means if I have a function like this:

 (defn exclaimer [bangs] #(apply str % (repeat bangs !)))

 then the following would be true: (= (exclaimer 10) (exclaimer 10)), 
 making functions behave a lot more like values. I would love to have this 
 particular feature too, although I'm having trouble coming up with a 
 non-contrived example.

 I'd like to hear some thoughts on this. Thanks!

 Matt



  -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.comjavascript:
 Note that posts from new members are moderated - please be patient with 
 your first post.
 To unsubscribe from this group, send email to
 clojure+u...@googlegroups.com javascript:
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- 
 You received this message because you are subscribed to the Google Groups 
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to clojure+u...@googlegroups.com

Re: Improving pprint behavior for anonymous functions

2014-04-25 Thread Greg D
I guess I don't understand the problem, or what is meant by all the return 
classes of partial are the same class.  A counter-example would be helpful.

Further transcript using the macro:
user= (def p6 (partial* + 1 2 3))
#'user/p6
user= (class p6)
clojure.core$partial$fn__4194
user= (def p10 (partial* + 1 2 3 4))
#'user/p10
user= (class p10)
clojure.core$partial$fn__4196
user= p6
(partial + 1 2 3)
user= p10
(partial + 1 2 3 4)
user= (p6 100)
106
user= (p10 100)
110

On Friday, April 25, 2014 2:33:50 PM UTC-7, Gary Trakhman wrote:

 That's not going to work, all the return classes of partial are the same 
 class.


 On Fri, Apr 25, 2014 at 5:26 PM, Greg D gregoir...@gmail.comjavascript:
  wrote:

 I don't know if this is considered good Clojure, but you could define a 
 print-method within a macro to set up the normal string representation for 
 the partial function:
 (defmacro partial* [fname arg0  args]
   `(let [pf#  (partial ~fname ~arg0 ~@args)
  cpf# (class pf#)]
  (defmethod print-method cpf# [o# w#]
(if (nil? '~args)
  (print-simple (str (partial  '~fname   (pr-str ~arg0) )) 
 w#)
  (print-simple (str (partial  '~fname   (pr-str ~arg0) ~@(map 
 #(str   (pr-str %)) args) )) w#)))
  pf#))

 A transcript of some quick examples:
 user= (def p6 (partial* + 1 2 3))
 #'user/p6
 user= p6
 (partial + 1 2 3)
 user= (p6 7)
 13
 user= (def re-find-foo (partial* re-find #foo))
 #'user/re-find-foo
 user= re-find-foo
 (partial re-find #foo)
 user= (re-find-foo abcdefooghi)
 foo


 On Friday, April 25, 2014 9:01:37 AM UTC-7, Matthew DeVore wrote:

 Hi,

 There has been one thing bugging me for a long time that seems worth it 
 to fix, and I was wondering if anyone else has had the same problem. I have 
 enjoyed using Clojure's REPL and embracing a Clojure-style data model for 
 my app, where everything is a glorified map or vector and there are no 
 private fields. I even have a simple dump feature that tells me the entire 
 state of my app https://github.com/google/hesokuri that was 
 ridiculously easy to implement, and that takes advantage of the lack of 
 black box data structures.

 One thing that doesn't really fit in this paradigm is (ironically) 
 anonymous functions with closures. For instance, (partial + 42) returns an 
 anonymous function, and in the REPL or an app dump, it looks hideous:
 #core$partial$fn__4228 clojure.core$partial$fn__4228@1ee1dea2

 So I've avoided anonymous functions in my app except when they exist 
 transiently, and don't appear in the dump (for instance, in (map #(str % 
 !) foo)). But sometimes I just can't avoid a long-lived anonymous 
 function practically. The best solution I've come up with is to transform 
 anonymous functions when preparing the application dump. (See the 
 implementationhttps://github.com/google/hesokuri/blob/b60cb7222cfdd672e394ef6f22b80c94278fe3a0/src/hesokuri/see.clj#L35)
  
 This makes (partial + 42) look like this:

 {:fn-class clojure.core$partial$fn__4228,
  arg1 42,
  f {:fn-class clojure.core$_PLUS_}}

 Which isn't great (I'd like to have filenames and line numbers for each 
 anon fn, and a nicer name for clojure.core/+), but it's a big improvement. 
 The function's JVM class and the closured values are revealed. It would be 
 nice to implement this natively. Having only passing familiarity with the 
 Clojure code base, to solve it I think one could:

- give anonymous functions a .getClosure method which creates a view 
of the closure on-demand
- (optional) change their .toString implementation to include this 
information
- add logic to clojure.pprint to use the .getClosure method (I guess 
(defmethod clojure.pprint/simple-dispatch clojure.lang.AFunction 
 etc...) 
?) 

 Another feature that would go nicely with this is smarter equality 
 semantics for anonymous functions, so that any two anonymous functions 
 generated at the same point in code with equal closures are equal. This 
 means if I have a function like this:

 (defn exclaimer [bangs] #(apply str % (repeat bangs !)))

 then the following would be true: (= (exclaimer 10) (exclaimer 10)), 
 making functions behave a lot more like values. I would love to have this 
 particular feature too, although I'm having trouble coming up with a 
 non-contrived example.

 I'd like to hear some thoughts on this. Thanks!

 Matt



  -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.comjavascript:
 Note that posts from new members are moderated - please be patient with 
 your first post.
 To unsubscribe from this group, send email to
 clojure+u...@googlegroups.com javascript:
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- 
 You received this message because you are subscribed to the Google Groups 
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send

Re: Improving pprint behavior for anonymous functions

2014-04-25 Thread Greg D
Got it. The macro, as is, will displace the print method for the same arity.

On Friday, April 25, 2014 2:50:34 PM UTC-7, Gary Trakhman wrote:

 Ah, I think I was mistaken in a detail, but generally correct.  Try it 
 with two partials of the same arity.


 https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L2460


 On Fri, Apr 25, 2014 at 5:47 PM, Greg D gregoir...@gmail.comjavascript:
  wrote:

 I guess I don't understand the problem, or what is meant by different 
 classes.  A counter-example would be helpful.

 Further transcript using the macro:
 (def p6 (partial* + 1 2 3))
 #'user/p6
 user= (class p6)
 clojure.core$partial$fn__4194
 user= (def p10 (partial* + 1 2 3 4))
 #'user/p10
 user= (class p10)
 clojure.core$partial$fn__4196

 user= p6
 (partial + 1 2 3)
 user= p10
 (partial + 1 2 3 4)
 user= (p6 100)
 106
 user= (p10 100)
 110

 On Friday, April 25, 2014 2:33:50 PM UTC-7, Gary Trakhman wrote:

 That's not going to work, all the return classes of partial are the same 
 class.


 On Fri, Apr 25, 2014 at 5:26 PM, Greg D gregoir...@gmail.com wrote:

 I don't know if this is considered good Clojure, but you could define a 
 print-method within a macro to set up the normal string representation for 
 the partial function:
 (defmacro partial* [fname arg0  args]
   `(let [pf#  (partial ~fname ~arg0 ~@args)
  cpf# (class pf#)]
  (defmethod print-method cpf# [o# w#]
(if (nil? '~args)
  (print-simple (str (partial  '~fname   (pr-str ~arg0) )) 
 w#)
  (print-simple (str (partial  '~fname   (pr-str ~arg0) 
 ~@(map #(str   (pr-str %)) args) )) w#)))
  pf#))

 A transcript of some quick examples:
 user= (def p6 (partial* + 1 2 3))
 #'user/p6
 user= p6
 (partial + 1 2 3)
 user= (p6 7)
 13
 user= (def re-find-foo (partial* re-find #foo))
 #'user/re-find-foo
 user= re-find-foo
 (partial re-find #foo)
 user= (re-find-foo abcdefooghi)
 foo


 On Friday, April 25, 2014 9:01:37 AM UTC-7, Matthew DeVore wrote:

 Hi,

 There has been one thing bugging me for a long time that seems worth 
 it to fix, and I was wondering if anyone else has had the same problem. I 
 have enjoyed using Clojure's REPL and embracing a Clojure-style data 
 model 
 for my app, where everything is a glorified map or vector and there are 
 no 
 private fields. I even have a simple dump feature that tells me the 
 entire 
 state of my app https://github.com/google/hesokuri that was 
 ridiculously easy to implement, and that takes advantage of the lack of 
 black box data structures.

 One thing that doesn't really fit in this paradigm is (ironically) 
 anonymous functions with closures. For instance, (partial + 42) returns 
 an 
 anonymous function, and in the REPL or an app dump, it looks hideous:
 #core$partial$fn__4228 clojure.core$partial$fn__4228@1ee1dea2

 So I've avoided anonymous functions in my app except when they exist 
 transiently, and don't appear in the dump (for instance, in (map #(str % 
 !) foo)). But sometimes I just can't avoid a long-lived anonymous 
 function practically. The best solution I've come up with is to transform 
 anonymous functions when preparing the application dump. (See the 
 implementationhttps://github.com/google/hesokuri/blob/b60cb7222cfdd672e394ef6f22b80c94278fe3a0/src/hesokuri/see.clj#L35)
  
 This makes (partial + 42) look like this:

 {:fn-class clojure.core$partial$fn__4228,
  arg1 42,
  f {:fn-class clojure.core$_PLUS_}}

 Which isn't great (I'd like to have filenames and line numbers for 
 each anon fn, and a nicer name for clojure.core/+), but it's a big 
 improvement. The function's JVM class and the closured values are 
 revealed. 
 It would be nice to implement this natively. Having only passing 
 familiarity with the Clojure code base, to solve it I think one could:

- give anonymous functions a .getClosure method which creates a 
view of the closure on-demand
- (optional) change their .toString implementation to include this 
information
- add logic to clojure.pprint to use the .getClosure method (I 
guess (defmethod clojure.pprint/simple-dispatch 
 clojure.lang.AFunction 
etc...) ?) 

 Another feature that would go nicely with this is smarter equality 
 semantics for anonymous functions, so that any two anonymous functions 
 generated at the same point in code with equal closures are equal. This 
 means if I have a function like this:

 (defn exclaimer [bangs] #(apply str % (repeat bangs !)))

 then the following would be true: (= (exclaimer 10) (exclaimer 10)), 
 making functions behave a lot more like values. I would love to have this 
 particular feature too, although I'm having trouble coming up with a 
 non-contrived example.

 I'd like to hear some thoughts on this. Thanks!

 Matt



  -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.com

 Note that posts from new members are moderated - please

Re: Improving pprint behavior for anonymous functions

2014-04-25 Thread Greg D
The code below accounts for partials of the same arity.  However, there 
might be a better way to do this with clojure.reflect:
(defn print-partial [a-fn]
  (let [c  (class a-fn)
fields (into {} (- c .getDeclaredFields
 (map #(vector (.getName %)
   (do (.setAccessible % true)
   (.get % a-fn))
f  (get fields f)
fname  (loop [[ns  namespaces] (all-ns)]
 (let [nsmap (into {} (map #(try (vector (deref (second %)) 
(first %))
 (catch Exception e
   [::e nil]))
   (ns-publics ns)))]
   (if-let [fname (get nsmap f)]
 #_(symbol (str ns) fname)
 (str (ns-name ns) / fname)
 (if (empty? namespaces)
   f
   (recur namespaces)
args   (loop [args 
  arg-num  1]
 (if-let [arg (get fields (str arg arg-num))]
   (recur (str args   (pr-str arg)) (inc arg-num))
   args))]
(str (partial  fname args 

(defmacro partial* [fname arg0  args]
  `(let [pf#  (partial ~fname ~arg0 ~@args)
 cpf# (class pf#)]
 (defmethod print-method cpf# [o# w#]
   (print-simple (print-partial o#) w#))
 pf#))

Trying out:
(def p6 (partial* + 1 2 3))
#'user/p6
user= p6
(partial clojure.core/+ 1 2 3)
user= (def t7 (partial* * 1 1 7))
#'user/t7
user= t7
(partial clojure.core/* 1 1 7)
user= p6
(partial clojure.core/+ 1 2 3)
user= (def comma-join (partial* clojure.string/join , ))
#'user/comma-join
user= comma-join
(partial clojure.string/join , )
user= (p6 100)
106
user= (t7 5)
35
user= (comma-join ['a 'b 'c])
a, b, c





On Friday, April 25, 2014 2:55:23 PM UTC-7, Greg D wrote:

 Got it. The macro, as is, will displace the print method for the same 
 arity.

 On Friday, April 25, 2014 2:50:34 PM UTC-7, Gary Trakhman wrote:

 Ah, I think I was mistaken in a detail, but generally correct.  Try it 
 with two partials of the same arity.


 https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L2460


 On Fri, Apr 25, 2014 at 5:47 PM, Greg D gregoir...@gmail.com wrote:

 I guess I don't understand the problem, or what is meant by different 
 classes.  A counter-example would be helpful.

 Further transcript using the macro:
 (def p6 (partial* + 1 2 3))
 #'user/p6
 user= (class p6)
 clojure.core$partial$fn__4194
 user= (def p10 (partial* + 1 2 3 4))
 #'user/p10
 user= (class p10)
 clojure.core$partial$fn__4196

 user= p6
 (partial + 1 2 3)
 user= p10
 (partial + 1 2 3 4)
 user= (p6 100)
 106
 user= (p10 100)
 110

 On Friday, April 25, 2014 2:33:50 PM UTC-7, Gary Trakhman wrote:

 That's not going to work, all the return classes of partial are the 
 same class.


 On Fri, Apr 25, 2014 at 5:26 PM, Greg D gregoir...@gmail.com wrote:

 I don't know if this is considered good Clojure, but you could define 
 a print-method within a macro to set up the normal string representation 
 for the partial function:
 (defmacro partial* [fname arg0  args]
   `(let [pf#  (partial ~fname ~arg0 ~@args)
  cpf# (class pf#)]
  (defmethod print-method cpf# [o# w#]
(if (nil? '~args)
  (print-simple (str (partial  '~fname   (pr-str ~arg0) 
 )) w#)
  (print-simple (str (partial  '~fname   (pr-str ~arg0) 
 ~@(map #(str   (pr-str %)) args) )) w#)))
  pf#))

 A transcript of some quick examples:
 user= (def p6 (partial* + 1 2 3))
 #'user/p6
 user= p6
 (partial + 1 2 3)
 user= (p6 7)
 13
 user= (def re-find-foo (partial* re-find #foo))
 #'user/re-find-foo
 user= re-find-foo
 (partial re-find #foo)
 user= (re-find-foo abcdefooghi)
 foo


 On Friday, April 25, 2014 9:01:37 AM UTC-7, Matthew DeVore wrote:

 Hi,

 There has been one thing bugging me for a long time that seems worth 
 it to fix, and I was wondering if anyone else has had the same problem. 
 I 
 have enjoyed using Clojure's REPL and embracing a Clojure-style data 
 model 
 for my app, where everything is a glorified map or vector and there are 
 no 
 private fields. I even have a simple dump feature that tells me the 
 entire 
 state of my app https://github.com/google/hesokuri that was 
 ridiculously easy to implement, and that takes advantage of the lack of 
 black box data structures.

 One thing that doesn't really fit in this paradigm is (ironically) 
 anonymous functions with closures. For instance, (partial + 42) returns 
 an 
 anonymous function, and in the REPL or an app dump, it looks hideous:
 #core$partial$fn__4228 clojure.core$partial$fn__4228@1ee1dea2

 So I've avoided anonymous functions in my app except when they exist 
 transiently, and don't appear in the dump (for instance, in (map #(str % 
 !) foo)). But sometimes I just can't

Re: puzzled by RuntimeException

2014-04-22 Thread Greg D
I believe this is a problem in REPL-y, which is used when using 'lein repl'.

I used Cider to start a nREPL server, then used 'leing repl :connect' to 
get the REPL-y interface.

The problem was evident in the latter, but not the former.  I opened an 
issue for REPL-y.

Thanks again, Steve

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


puzzled by RuntimeException

2014-04-21 Thread Greg D
The sequence in the transcript below shows runtime exceptions when a 
numeric keyword is followed by a list starting with a symbol or character.

Would anyone help me with a reason for the failing cases?

user= (clojure-version)
1.6.0
user= '(:42 a)
(:42 a)
user= '(:42 a)
(:42 a)
user= '(:42 \a)
(:42 \a)
user= '(:42 nil)
(:42 nil)
user= '(:42 true)
(:42 true)
user= '(:42 :43)
(:42 :43)
user= '(:42 (a))

RuntimeException EOF while reading, starting at line 1  
clojure.lang.Util.runtimeException (Util.java:221)

RuntimeException Unmatched delimiter: )  clojure.lang.Util.runtimeException 
(Util.java:221)
user= '(:42 (a))
(:42 (a))
user= '(:42 (\a))

RuntimeException EOF while reading, starting at line 1  
clojure.lang.Util.runtimeException (Util.java:221)
RuntimeException Unmatched delimiter: )  clojure.lang.Util.runtimeException 
(Util.java:221)

user= '(:42 (nil))

RuntimeException EOF while reading, starting at line 1  
clojure.lang.Util.runtimeException (Util.java:221)

user= RuntimeException Unmatched delimiter: )  
clojure.lang.Util.runtimeException (Util.java:221)


user= '(:42 (true))

RuntimeException EOF while reading, starting at line 1  
clojure.lang.Util.runtimeException (Util.java:221)

user= RuntimeException Unmatched delimiter: )  
clojure.lang.Util.runtimeException (Util.java:221)


user= '(:42 (:43))
(:42 (:43))
user= 

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: puzzled by RuntimeException

2014-04-21 Thread Greg D

Steve,

Thanks.  I did a quick check, and it seems that I don't get exceptions when 
I start the repl as you do.

I normally start mine with 'lein repl'.  You've given me a good lead to 
investigate.

Greg

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Thoughts on bags?

2014-04-19 Thread Greg D
While searching for MultiSet or Bag resources, I found this implementation 
by Achim Passen at: A simple multiset/bag implementation for Clojure.

However, I found I could meet my needs by adding functions to treat 
vectors, or other collection types, as unordered. These can then be used 
directly, or in the definition of your own specialized types.

For the hash, from Clojure Data Structures:

(defn hash-unordered [collection]
  (- (reduce unchecked-add-int 0 (map hash collection))
  (mix-collection-hash (count collection


For equality:
(defn equals-unordered [coll-a coll-b]
  Treat collections as unordered for 1st level of comparison.
  (or (identical? coll-a coll-b)
  (and (empty? coll-a) (empty? coll-b))
  (and (= (hash-unordered coll-a) (hash-unordered coll-b))
   (let [set-a (set coll-a)
 set-b (set coll-b)]
 (and (= set-a set-b)
  (loop [[item  items] (seq set-a)]
(let [finder #(= item %)
  found-a (filter finder coll-a)
  found-b (filter finder coll-b)]
  (if (not= (count found-a) (count found-b))
false
(if (empty? items)
  true
  (recur items))

Neither Achim's deftype, nor the above, is likely as efficient as 
implementation as a core collection MultiSet.

The attached file has a trivial implementation of a deftype showing the 
functions in use. It defines a shopping cart where the items are kept on a 
vector, which is treated as an unordered collection. A transcript of 
playing with the shopping cart follows:

user= (load-file shopping_cart.clj)
#'example.multi-set/make-shopping-cart
user= (use 'example.multi-set)
nil
user= (def cart0 (make-shopping-cart 'carrots 'beans 'eggs))
#'user/cart0
user= cart0
(make-shopping-cart carrots beans eggs)
user= (def cart1 (make-shopping-cart 'eggs 'carrots 'beans))
#'user/cart1
user= cart1
(make-shopping-cart eggs carrots beans)
user= (def cart2 (make-shopping-cart 'ham 'eggs 'carrots 'beans))
#'user/cart2
user= cart2
(make-shopping-cart ham eggs carrots beans)
user= (= cart0 cart1)
true
user= (= cart1 cart2)
false  

Greg

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


shopping_cart.clj
Description: Binary data


Re: Thoughts on bags?

2014-04-19 Thread Greg D
Added link missing in previous post.

A simple multiset/bag implementation for 
Clojurehttps://github.com/achim/multiset

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Thoughts on bags?

2014-04-17 Thread Greg D
While searching for MultiSet or Bag resources, I found this implementation 
by Achim Passen at: A simple multiset/bag implementation for 
Clojurehttps://github.com/achim/multiset
.

However, I found I could meet my needs by adding functions to treat 
vectors, or other collection types, as unordered.

For the hash, from Clojure Data 
Structureshttp://clojure.org/data_structures#hash
:

(defn hash-unordered [collection]
  (- (reduce unchecked-add-int 0 (map hash collection))
  (mix-collection-hash (count collection


For equality:
(defn equals-unordered [coll-a coll-b]
  Treat collections as unordered for 1st level of comparison.
  (or (identical? coll-a coll-b)
  (and (empty? coll-a) (empty? coll-b))
  (let [set-a (set coll-a)
set-b (set coll-b)]
(and (= set-a set-b)
 (loop [[item  items] (seq set-a)]
   (let [finder #(= item %)
 found-a (filter finder coll-a)
 found-b (filter finder coll-b)]
 (if (not= (count found-a) (count found-b))
   false
   (if (empty? items)
 true
 (recur items)

Neither Achim's deftype, nor the above, is likely as efficient as a core 
collection MultiSet. In the meantime, I hope these observations are useful.

Greg

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Questions regarding Map vs Record and usage

2014-04-09 Thread Greg D
FWIW, I use:

   - (-Book Lord of the Rings, Tolkien)
  - when I define the record instance with the default fields, and the 
  number of default fields is a small number
   - (map-Book {:title The Fellowship of the Ring,
  :author Tolkien,
  :series The Lord of the Rings,
  :publisher Mariner Books,
  :year 2012,
  :ISBN-10 0547928211,
  :my-rating 10}) 
  - The explicit key names are good documentation when 
  - there are many fields in the defrecord, or
 - when adding entries not in the defrecord (eg. my-rating)
  
Greg

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


self-evaluation of record instances

2014-04-02 Thread Greg D
Greetings,

The nuance below took a long time to identify and reduce from a test 
failure. Should it be considered a bug?

$ lein repl
nREPL server started on port 52758 on host 127.0.0.1
REPL-y 0.3.0
Clojure 1.6.0
snipped

user= (defrecord Fields0 [])  ; record with 0 fields
user.Fields0
user= (defrecord Fields1 [f]) ; record with 1 field
user.Fields1
user= (def f0 (-Fields0)); instance with empty map
#'user/f0
user= (def f0x (map-Fields0 {:x 0})) ; instance with not-empty map, due 
to extra field
#'user/f0x
user= (def f1 (map-Fields1 {}))  ; instance with not-empty map, 
declared field is nil
#'user/f1
user= f0
#user.Fields0{}
user= f0x
#user.Fields0{:x 0}
user= f1
#user.Fields1{:f nil}
user= (eval f0)   ; *** morphs to empty map on eval ***
{}
user= (eval f0x)  ; self-evaluates when non-empty map, 
field added
#user.Fields0{:x 0}
user= (eval f1)   ; self-evaluates when non-empty map, 
declared field
#user.Fields1{:f nil}
user= 

Greg

p.s. A little help with not quite getting 
refshttps://groups.google.com/forum/#!topic/clojure/o9FiG1kCt6I, 
please? Or is this the wrong forum for such a question?

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


not quite getting refs

2014-03-26 Thread Greg D
I've looked, but can't find, a discussion of the choice of a history 
mechanism for refs.

I can't understand why the transactions just don't check #'identical? for 
the ref value, rather than maintaining a history queue. In other words, I 
don't see why
(dosync (ref-set foo @foo)))
should cause other ongoing transactions, that use foo, to retry. Nothing 
about foo has changed that will alter a retried transaction.

Since an #'identical? mechanism would seem to

   - be easier to implement
   - be faster to check at the end of a tranaction
   - cause fewer retries

it must be that I don't really get it yet. Does anyone have a doc pointer 
that would help with the details?

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: STM history queues, when is a snapshot pushed

2014-03-24 Thread Greg D
Having learned a little more about refs and transactions from M. Fogus and 
C. Houser The Joy of Clojure, Second Editionhttp://www.manning.com/fogus2/, 
I altered the stress-ref function from 10.2.4. Using Clojure 1.5.1:

(defn stress-ref [r]
  (let [slow-tries (atom 0)]
(future
 (dosync
  (swap! slow-tries inc)
  (Thread/sleep 200)
  @r)
 (println (format r is: %s, meta: %s, history: %d, after: %d tries
  @r (meta @r) (.getHistoryCount r) @slow-tries)))
(dotimes [i 500]
  (Thread/sleep 10)
  (dosync (alter r #(let [r0 (first %)]
 (condp = r0
 :identical %
 := (with-meta % {:mkw (inc (:mkw (meta 
%)))})
 (with-meta [(inc r0)] {:mkw (inc (:mkw (meta 
%)))}))
:done))

Using this function in the following ways
user= (stress-ref (ref (with-meta [:identical] {:mkw 0})))
:done
r is: [:identical], meta: {:mkw 0}, history: 10, after: 26 tries

user= (stress-ref (ref (with-meta [:=] {:mkw 0})))
:done
r is: [:=], meta: {:mkw 500}, history: 10, after: 26 tries

user= (stress-ref (ref (with-meta [0] {:mkw 0})))
:done
r is: [500], meta: {:mkw 500}, history: 10, after: 26 tries

From these results I infer that a snapshot is pushed to history whenever 
alter (et al) are used. Any efficiencies need to be implemented in the 
Clojure code, eg.
(defn stress-ref-equal [r]
  (let [slow-tries (atom 0)]
(future
 (dosync
  (swap! slow-tries inc)
  (Thread/sleep 200)
  @r)
 (println (format r is: %s, meta: %s, history: %d, after: %d tries
  @r (meta @r) (.getHistoryCount r) @slow-tries)))
(dotimes [i 500]
  (Thread/sleep 10)
  (dosync (let [r0 (first @r)]
(condp = r0
:identical (ensure r)
:= (ensure r)
(alter r #(with-meta [(inc r0)] {:mkw (inc (:mkw (meta 
%)))}))
:done))

user= (stress-ref-equal (ref (with-meta [:identical] {:mkw 0})))
r is: [:identical], meta: {:mkw 0}, history: 0, after: 1 tries
:done

user= (stress-ref-equal (ref (with-meta [:=] {:mkw 0})))
r is: [:=], meta: {:mkw 0}, history: 0, after: 1 tries
:done

user= (stress-ref-equal (ref (with-meta [0] {:mkw 0})))
:done
r is: [500], meta: {:mkw 500}, history: 10, after: 26 tries

The documentation at Refs and Transactions http://clojure.org/refs only 
refers to change without defining what is meant by change. Given the 
admonition not to rely on inferences as made above, what's a coder to do? 
Future optimization of refs and transactions may break the code.

As a beginner, I can't tell if I'm just confused, or if this is actually 
confusing.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


STM history queues, when is a snapshot pushed

2014-03-23 Thread Greg D
Is a new snapshot pushed onto the history queue of a ref when

   1. every time the ref is a target of alter, commute, ref-set, reset, 
   alter-meta!, or reset-meta!, or
   2. only when the committed value for the ref is not identical to the 
   value at the end of the history queue?
   
When checking the committability of a ref before the end of a transaction, 
is the check that

   1. the end position of the history queue for that ref is the same as it 
   was at the beginning of the transaction, or
   2. the value of the ref at the end of the history queue is identical to 
   the value at the beginning of the transaction?

For both questions, choice 1 appears to be unquestionable safe, but could 
sponsor a higher number of retries. The choice 2s may conserve some 
retries, but I'm not sure about the safety. 

For both questions, the implementation complexity and efficiency seem 
similar.

At any rate, the actual implementation is not a part of the documented API, 
yet could affect how one codes transaction functions. Even if I dug through 
the Java source to form my own impressions, one is not supposed to rely on 
such behaviour.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


non-equality (=) of records nuance

2014-03-18 Thread Greg D
Greetings,

I'm confused by the failure of 2 record instances to compare as equal, only 
when generated by a protocol method and having extra fields.

The code below shows this, with uninformative REPL responses snipped. The 
attached file has similar code as a clojure.test.

Would somebody please help me understand the underlying mechanism. I'll 
need to develop a workaround to avoid confounding library users.

Thanks, Greg

user= ;;; Set up protocol and records
user= (defprotocol FooBar (clone [this]) (switch [this]))
user= (defrecord Foo [])
user= (defrecord Bar [])
user= (extend-type Foo FooBar (clone [this] (map-Foo this)) (switch 
[this] (map-Bar this)))
user= (extend-type Bar FooBar (clone [this] (map-Bar this)) (switch 
[this] (map-Foo this)))

user= ;;; Create 4 (.equal) instances of Bar, no fields; all works as 
expected
user= (def foo0 (-Foo))
user= (def bar0 (-Bar))
user= (def bar1 (-Bar))
user= (def bar-switch-foo0 (switch foo0))
user= (def bar-clone-bar0 (clone bar0))
user= bar0
#user.Bar{}
user= bar1
#user.Bar{}
user= bar-switch-foo0
#user.Bar{}
user= bar-clone-bar0
#user.Bar{}
user= (= bar0 bar1); gets expected true
true
user= (= bar0 bar-switch-foo0) ; gets expected true
true
user= (= bar0 bar-clone-bar0)  ; gets expected true
true

user= ;;; Create 4 (.equal) instances of Bar with an added field; 
unexpected results
user= (def x-foo0 (map-Foo {:field xtra}))
user= (def x-bar0 (map-Bar {:field xtra}))
user= (def x-bar1 (map-Bar {:field xtra}))
user= (def bar-switch-x-foo0 (switch x-foo0))
user= (def bar-clone-x-bar0 (clone x-bar0))
user= x-bar0
#user.Bar{:field xtra}
user= x-bar1
#user.Bar{:field xtra}
user= bar-switch-x-foo0
#user.Bar{:field xtra}
user= bar-clone-x-bar0
#user.Bar{:field xtra}
user= (= x-bar0 x-bar1); gets expected true
true
user= (= x-bar0 bar-switch-x-foo0) ; gets UNEXPECTED
false
user= (= x-bar0 bar-clone-x-bar0)  ; gets UNEXPECTED
false
user= (= bar-switch-x-foo0 bar-clone-x-bar0)   ; gets UNEXPECTED
false
user= (.equals x-bar0 bar-switch-x-foo0)   ; .equals is true
true
user= (.equals x-bar0 bar-clone-x-bar0); .equals is true
true
user= (.equals bar-switch-x-foo0 bar-clone-x-bar0) ; .equals is true
true

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


record_instance_equality_test.clj
Description: Binary data


Re: non-equality (=) of records nuance

2014-03-18 Thread Greg D
I'm on 1.5.1

I have a workaround:

   - instead of 
   - (map-Foo this)
   - use
  -  (map-Foo (into {} this))
  

On Tuesday, March 18, 2014 5:47:46 PM UTC-7, Alex Miller wrote:

 What Clojure version are you on?

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.