Re: Why I'm getting StackoverflowError?

2010-12-05 Thread Danny Woods
On Dec 5, 9:52 pm, HB hubaghd...@gmail.com wrote:
 Hi,
 I'm trying to write a function that calculates the length of a list:

 (defn list-length [col]
   (if col
     (+ 1 (list-length(rest col)))
     0))

 (list-length '(Java, Clojure, Scala))

 Upon running it in the REPL, I got the error:
 java.lang.StackOverflowError (test.clj:3)

 What is going wrong?

Unlike Common Lisp, the empty list is not a false value in Clojure, so
your condition is always true.

If you change your test to (if (empty? col) ... ), all should be good.

Cheers,
Danny.

-- 
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


Re: One benefit of having a REPL

2009-11-29 Thread Danny Woods
On Nov 28, 1:20 pm, John Harrop jharrop...@gmail.com wrote:
 One benefit of having a REPL: it makes regular expressions usable. So easy
 to test and tweak your RE compared to the traditional compile/test/debug
 cycle! I never even bothered with the java.util.regex package before Clojure
 as it was too painful to use.


You just reminded me of a utility I wrote in Ruby some years ago to
interactively build regular expressions.  I hacked up a Clojure
version in the past hour or so, and pushed it up to github at
http://github.com/dannywoodz/regex-toolbox.

Unfortunately, I can't claim to have come up with the idea, but
implementing it was good fun. :-)

Feedback always welcome!

Cheers,
Danny.

-- 
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


Re: Deep deref

2009-11-15 Thread Danny Woods
 Danny, could you maybe hack up a possible very simple example of what
 you mean?

snip

 I can not simply store a copy of the Karl person in Tinas :friends
 slot,
 because when Karl gets one year older, then I don‘t want to go through
 all persons, looking for Karls, and have their age updated.

Hi André,

Your shared instance constraint does make things a little more
interesting than in my application, but I think John's suggestion
about not storing friend instances directly is a good thing.  If you
were to instead assign an id to each created person, and have each
friend list be a list of ids, the entity referred to by the id can
still be immutable for a given dereference.  Not sure how much sense
that makes, so here's something crude that I've hacked up:

(def *everyone* (ref {}))
(def *global-id* (ref 0))

(defn next-id [] (dosync (commute *global-id* inc)))

(defstruct person :name :friend-ids :id)

(defn make-person [name] (struct person name [] (next-id)))

(defn make-and-add-person [name]
  (let [person (make-person name)]
(dosync (alter *everyone* assoc (:id person) person

(defn befriend [person friend]
  (let [new-friend-list (conj (:friend-ids person) (:id friend))
new-person (assoc person :friend-ids new-friend-list)]
(dosync
 (alter *everyone* assoc (:id person) new-person

The 'down side' here is simply that you refer to people by ids, rather
than directly, but the up side is that a given deref of *everyone* is
immutable and consistent.

Cheers,
Danny.

-- 
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


Re: Deep deref

2009-11-14 Thread Danny Woods
André Thieme wrote:
 How can we handle this situation?
 Is it possible to implement a function “deep-deref” which works
 as blindingly fast as deref does?
 I find this very important, and this is of great practical relevance
 for me. Please share your ideas

Hi André,

I had a similar issue with an application I wrote a while back.  The
initial structure was simple: a grid-based map, containing a number of
entities, each entity having a name, an owner, dimensions, etc.  The
map was behind a ref, and the entities were initially refs themselves,
embedded within the map structure.  Then I realised that it was
difficult to know with certainty what was in the deref'd map.

It kind of struck me then that I was thinking about the problem
incorrectly.  My object-oriented hat made me want to have the map and
entities as separate things, each in charge of its own state.  When I
re-wrote the code so that the entities were themselves an immutable
part of an immutable map, and that changes to entities resulted in an
*entirely new map*, those problems went away.  All the various
interactions with the UI and with the network updated the map and
entities transactionally, with a new, consistent map after each
alteration.  What a relief that was!

In your case, adding someone to a friend list should result in what is
conceptually a completely new database, that shares almost all of its
structure with its predecessor.  This top-level structure can sit
behind a ref, with immutable person structs as constituent parts.
This makes proper use of immutability and negates the need for a deep
deref.

That's just my experience.  I'd be interested to know if anyone has an
honest need for refs within refs (especially in a larger system).

Cheers,
Danny.

-- 
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


Re: Beginner: performance of vector creation/modification

2009-10-19 Thread Danny Woods

harto wrote:
 Hello,

 I've just started learning Clojure, so I'm trying to figure out the
 correct way of doing things. I've been trying to create and 'modify' a
 large vector for an online programming exercise, but I'm running into
 some performance issues.

 Any general tips would be appreciated!
   

Well, I'm a beginner too, but I'll take a stab at answering your questions.

 Firstly, I'm creating a vector of booleans like this:

 (defn vector-of [n value]
   (vec (for [_ (range n)] value)))

 It takes quite a long time for large values of n, though:

 user= (time (dorun (vector-of 1e7 true)))
 Elapsed time: 6734.509528 msecs
   
I suspect you're being bitten by the repeated creation of the underlying
data structures.  'range' is going to create a lazy sequence, from which
'for' is going to create its own, lazy structure, which 'vec' then
iterates over to create its own.  Just running '(time (dorun (range
1e7)))' shows that it's taking up a non-trivial amount of time just on
its own.

This modified version does the same thing a little more quickly:

(defn vector-of [n value]
  (loop [v []
 c 0]
(if ( c n) (recur (assoc v c value) (inc c)

user (time (dorun (vector-of 1e7 true)))
Elapsed time: 1000.409039 msecs

 Secondly, I'm iterating across one of these large vectors using
 something like the following (contrived) function:

 (defn set-flags [v]
   (loop [i 0
  v v]
 (if ( i (count v))
 (recur (inc i) (assoc v i false))
 v)))

 user= (let [v (vector-of 1e7 true)] (time (dorun (set-flags v
 Elapsed time: 15563.916114 msecs

 Am I missing anything obvious here? That seems like a really long time
 to me.
   
With the modified vector-of, above, this problem seems to go away for me:

user (time (dorun (set-flags (vector-of 1e7 true
Elapsed time: 1009.362723 msecs

Cheers,
Danny.

--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: Beginner: performance of vector creation/modification

2009-10-19 Thread Danny Woods
Strangely, I'm not seeing my own emails turn up in this list...

Anyways, after re-reading what I sent, it only partially applies :-)  
The obvious (deliberate, of course) mistake with my vector-of was that I 
didn't return the vector that I'd built up! So set-flags was, of course, 
rather fast in dealing with nil.  Oops.  So the (kind of proper) 
implementation would be:


(defn vector-of [n value]
  (loop [v []
 c 0]
(if ( c n)
  (recur (assoc v c value) (inc c))
  v)))

The only thing that I can see that would speed up set-flags would be to 
not take the length of the vector on every iteration: I suspect that may 
involve a traversal of the vector every time it's called.

Cheers,
Danny.

On 19/10/2009 13:37, Stuart Campbell wrote:
 2009/10/19 Danny Woods dannywo...@gmail.com 
 mailto:dannywo...@gmail.com


 harto wrote:
  Hello,
 
  I've just started learning Clojure, so I'm trying to figure out the
  correct way of doing things. I've been trying to create and
 'modify' a
  large vector for an online programming exercise, but I'm running
 into
  some performance issues.
 
  Any general tips would be appreciated!
 

 Well, I'm a beginner too, but I'll take a stab at answering your
 questions.

  Firstly, I'm creating a vector of booleans like this:
 
  (defn vector-of [n value]
(vec (for [_ (range n)] value)))
 
  It takes quite a long time for large values of n, though:
 
  user= (time (dorun (vector-of 1e7 true)))
  Elapsed time: 6734.509528 msecs
 
 I suspect you're being bitten by the repeated creation of the
 underlying
 data structures.  'range' is going to create a lazy sequence, from
 which
 'for' is going to create its own, lazy structure, which 'vec' then
 iterates over to create its own.  Just running '(time (dorun (range
 1e7)))' shows that it's taking up a non-trivial amount of time just on
 its own.


 Ah, OK. I didn't understand the implications of using those lazy 
 sequences. I think I need to do some more reading on lazy data structures.

 Thanks for your input!


 This modified version does the same thing a little more quickly:

 (defn vector-of [n value]
  (loop [v []
 c 0]
(if ( c n) (recur (assoc v c value) (inc c)

 user (time (dorun (vector-of 1e7 true)))
 Elapsed time: 1000.409039 msecs


  Secondly, I'm iterating across one of these large vectors using
  something like the following (contrived) function:
 
  (defn set-flags [v]
(loop [i 0
   v v]
  (if ( i (count v))
  (recur (inc i) (assoc v i false))
  v)))
 
  user= (let [v (vector-of 1e7 true)] (time (dorun (set-flags v
  Elapsed time: 15563.916114 msecs
 
  Am I missing anything obvious here? That seems like a really
 long time
  to me.
 
 With the modified vector-of, above, this problem seems to go away
 for me:

 user (time (dorun (set-flags (vector-of 1e7 true
 Elapsed time: 1009.362723 msecs

 Cheers,
 Danny.



 


--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: Proposal: New Reader Macro #s{ ... }

2009-10-12 Thread Danny Woods

Perl and Ruby do something similar with regular expressions, where the
character following 'm' or 's' becomes the delimiter for that
expression, making 'm/\/some\/path/' identical to 'm!/some/path!'.  The
delimeter can be 'smart' as well, where the closing delimiter is
dependent upon the opening one (in the case of brackets, parentheses and
braces) leading to expressions like 'm(/some/path)'.  It would be really
handy if Clojure had a similar #s!!, #s(), #s//, etc. facility.

John Harrop wrote:
 How about borrowing a page from LaTeX? That has a \verb+text+ which
 can use any desired delimiter character. My thought is to have
 something like $+.+ turning whatever was between the character
 following $ (here, +) until the next occurrence of that character into
 a literal string. A way to escape the chosen character is still
 desirable, though it could be chosen in most cases not to be needed.
 Perhaps the sequence $+ recurring would translate to a literal + (and
 any other $x digraph into a literal $x digraph). $ seems like a good
 choice because it suggests the letter s, as in string, is not already
 overloaded in Clojure for some following symbols (unlike #), and very
 rarely occurs in text with a nonwhitespace character afterward. (This
 post stands as an obvious exception, but even then, I've used $+ and
 $x only so using a third nonwhitespace character after the $ would
 allow quoting this post verbatim in the same manner.)
 Sole limitation on the following character would be that it not be
 whitespace (a stand-alone $ would be treated the same as it currently
 is, as would a $ with no leading whitespace, so referencing nested
 Java classes would not be broken; multicharacter symbols starting with
 $ would be but I expect there is as of yet little or no preexisting
 code with such symbols).

 


--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: What books have helped you wrap your brain around FP and Clojure?

2009-06-07 Thread Danny Woods

+1 for Higher Order Perl.  The author, Mark Jason Dominus, has made
the book available for free download at http://hop.perl.plover.com/book/.

Cheers,
Danny.

--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---