Re: Implementing destructuring without setting your hair on fire

2011-01-21 Thread Mark Triggs
Daniel Werner daniel.d.wer...@googlemail.com writes:

 After a few tries I've come up with the following algorithm to
 transform :keys syntax into normal destructuring syntax, but am still
 appalled by its complexity:

 (let [vmap {'y :y, 'z :z :keys ['a 'b]}]
   (- vmap
 ((juxt :keys :strs :syms))
 (apply concat)
 (mapcat #(vector % (keyword %)))
 (apply hash-map)))

 == {a :a, b :b}


Pretty's such a subjective thing, but my first impulse was:

  (let [vmap {'y :y, 'z :z :keys ['a 'b]}]
(reduce #(assoc %1 %2 (keyword %2))
{}
(mapcat vmap [:keys :strs :syms])))


-- 
Mark Triggs
mark.h.tri...@gmail.com

-- 
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: filtering with multiple predicates

2010-07-24 Thread Mark Triggs
I cheated and used 'every?' :)

  (defn andf [ preds]
(fn [ args]
  (every? #(apply % args) preds)))


.Bill Smith william.m.sm...@gmail.com writes:

 I want to filter a list based on the logical AND of a set of
 predicates.  For example, let's say I have single-argument functions
 f, g, and h (without side-effects), and I want those items x in the
 list such that (f x), (g x) and (h x) are all true.  I know I can do
 this:

 (filter #(and (f %) (g %) (h %)) my-list)

 Is there a more terse way to express the same thing?  I suspect there
 is a mechanism similar to (or perhaps a generalization of) composition
 for that, but I couldn't find it in the API docs.

 Bill Smith
 Austin, TX

-- 
Mark Triggs
mark.h.tri...@gmail.com

-- 
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: filtering with multiple predicates

2010-07-24 Thread Mark Triggs
j-g-faustus johannes.fries...@gmail.com writes:

 I was apparently too late. Oh well :)

My apologies for pre-emptively stealing your idea :)

-- 
Mark Triggs
mark.h.tri...@gmail.com

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


Another `line-seq' issue

2010-03-11 Thread Mark Triggs
Hi all,

At the risk of being labelled the guy who always whines about
line-seq, I'm whining about line-seq again.  I hit some surprising
behaviour stemming from the fact that line-seq isn't fully lazy:

  (defn line-seq
Returns the lines of text from rdr as a lazy sequence of strings.
rdr must implement java.io.BufferedReader.
[#^java.io.BufferedReader rdr]
(when-let [line (.readLine rdr)]
  (cons line (lazy-seq (line-seq rdr)

This implementation is fully lazy:

  (defn line-seq [rdr]
(lazy-seq
  (when-let [line (.readLine rdr)]
(cons line (line-seq rdr)

but doesn't return nil on an empty sequence, which I think is why
line-seq was changed in the first place (commit
efc54c000445f8b3d8d2e75d560fa02397951598).

It seems that there's an inherent trade-off between wanting to return
nil for an empty sequence and wanting to be fully lazy, so I'm not sure
of the best way of achieving both objectives.  I just thought I'd raise
the issue in case someone brighter than me has any good ideas :)

Cheers,

Mark

-- 
Mark Triggs
mark.h.tri...@gmail.com

-- 
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: Small line-seq regression?

2009-12-14 Thread Mark Triggs
Drew Raines aarai...@gmail.com writes:

 Rich Hickey wrote:

 On Mon, Dec 14, 2009 at 8:48 AM, Chouser chou...@gmail.com wrote:

 [...]

 Your analysis and solution seem right to me.  Rich, would you
 accept a ticket for this?


 Yes, and could someone please check the other functions that were
 patched similarly?

 I'll do it since I created the original patch.

 https://www.assembla.com/spaces/clojure/tickets/222


Many thanks everyone.

Cheers,

Mark

-- 
Mark Triggs
mark.h.tri...@gmail.com

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


Small line-seq regression?

2009-12-13 Thread Mark Triggs
Hi all,

I recently pulled down the latest Clojure master branch and have noticed
a small change in line-seq's behaviour which breaks some of my code.
The code in question uses line-seq like this:

  (use 'clojure.contrib.duck-streams)
  (with-open [ss (java.net.ServerSocket. 4141)]
(println (first (line-seq (reader (.accept ss))

If I run this then telnet to the listen port and send a single line:

  Trying 127.0.0.1...
  Connected to localhost.
  Escape character is '^]'.
  hi

The above code prints nothing until the *second* line arrives from the
socket, even though that line isn't required to fulfil my (first ...)
request.  It appears this behaviour changed in patch 284ee8aa in an
effort to make line-seq return nil (instead of ()) for an empty lazy
seq.  The line-seq definition currently reads:

  (defn line-seq
Returns the lines of text from rdr as a lazy sequence of strings.
rdr must implement java.io.BufferedReader.
[#^java.io.BufferedReader rdr]
(let [line  (. rdr (readLine))]
  (when line
(lazy-seq (cons line (line-seq rdr))

and when my code above is blocked, it's because my call to 'first' has
caused the first recursive call to be made, which immediately blocks on
the now-eagerly-performed readLine for the second line of input.  Taking
the line to be returned out of the lazy-seq seems to fix things for me:

  (defn line-seq
Returns the lines of text from rdr as a lazy sequence of strings.
rdr must implement java.io.BufferedReader.
[#^java.io.BufferedReader rdr]
(let [line  (. rdr (readLine))]
  (when line
(cons line (lazy-seq (line-seq-new rdr))

and, I think, still preserves the intention of the original change.
Does that seem reasonable?

Thanks,

Mark

-- 
Mark Triggs
mark.h.tri...@gmail.com

-- 
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: Specified behavior of every?

2009-12-02 Thread Mark Triggs
I've always relied on this being true without losing sleep at night (or
during the day), and it has a good grounding in predicate logic:

  http://en.wikipedia.org/wiki/Universal_quantification#The_empty_set

Cheers,

Mark


Sean Devlin francoisdev...@gmail.com writes:

 The following return true:

 user=(every? even? nil)
 true

 user=(every? even? [])
 true

 Is this behavior the specified behavior?  Can I ASSUME it is true in
 my code?

-- 
Mark Triggs
mark.h.tri...@gmail.com

-- 
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: Krishnamurthi's Automata in Clojure (OutOfMemoryError)

2009-11-27 Thread Mark Triggs
Hi Charles,

I notice I can stop your version from running out of memory with a very
small change.  Changing from:

  ;; the [f  args] form of trampoline
  (trampoline init start-stream)

to:

  ;; the [f] form of trampoline
  (trampoline #(init start-stream))

seems to work as expected.  I would hazard a guess that this might be
the same issue as described in this thread:

  http://groups.google.com/group/clojure/msg/dfb1c1d68ac7e742

Cheers,

Mark


Charles Gordon charles.gor...@gmail.com writes:

 The implementation listed there doesn't work, and is before Rich
 introduced letfn, so I decided to try my own implementation using
 letfn and trampoline:

 (defn machine [start-stream]
   (letfn [(init [stream]
 #(cond (empty? stream) true
 (= \c (first stream)) (more (rest stream))
 :else false))
   (more [stream]
 #(cond (empty? stream) true
 (= \a (first stream)) (more (rest stream))
 (= \d (first stream)) (more (rest stream))
 (= \r (first stream)) (end (rest stream))
 :else false))
   (end [stream]
#(cond (empty? stream) true
:else false))]
 (trampoline init start-stream)))

 This works, but if I try to run it on an infinite sequence, it
 eventually runs out of memory:

 (machine (iterate (fn [c] (if (= c \c) \a \d)) \c))

 Java heap space
   [Thrown class java.lang.OutOfMemoryError]

-- 
Mark Triggs
mark.h.tri...@gmail.com

-- 
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: Extend behavior of hash-map

2009-11-17 Thread Mark Triggs
How about?:

  (java.util.HashMap. {:a 1 :b 2 :c 3})

  = #HashMap {:c=3, :b=2, :a=1}


Mark

Sean Devlin francoisdev...@gmail.com writes:

 Okay golfers.  Is there a better way to do this?

 (defn put-all!
   [java-map clj-map]
   (do
   (doseq [entry clj-map]
   (.put java-map (key entry) (val entry)))
   java-map))

 user=(put-all (java.util.HashMap. ) {:a 1 :b 2 :c 3})
 #HashMap {:c=3, :b=2, :a=1}

 I already tried into :)

-- 
Mark Triggs
mark.h.tri...@gmail.com

-- 
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: Starting swank separately and connecting to it works almost but no REPL

2009-09-05 Thread Mark Triggs

Hi Mathias,

This wouldn't just be because SLIME no longer includes the REPL by
default, would it?  Does adding:

  (require 'slime-fancy)

to your emacs setup help at all?

Cheers,

Mark


Mathias Dahl mathias.d...@gmail.com writes:

 Hi!

 I am trying to start swank separately so that I can connect to it from
 a separate emacs instance. It works almost all the way but I never get
 a REPL. Here are the details:


[...]

 In emacs -Q:

 (add-to-list 'load-path ~/clj/slime)
 (require 'slime)
 (slime-setup)

 M-x slime-connect RET RET

 In the *Messages* buffer I can see this:

 Connecting to Swank on port 4005.. [2 times]
 Connected. Hack and be merry!

 I can then enter slime-mode and for example eval (+ 1 2) in a buffer
 and I
 get as reply 3 in the echo area.

 So, all seems to be setup properly and working. But, I get no REPL.
 Why?

-- 
Mark Triggs
mark.h.tri...@gmail.com

--~--~-~--~~~---~--~~
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: Idiom for array slicing

2009-08-18 Thread Mark Triggs

Yep, this was my thinking too.  Maybe it doesn't matter, but I'm always
a little reluctant to make those sort of compromises when writing
general-purpose utility functions.

Mark


Andrew Baine andrew.ba...@gmail.com writes:

 If coll has O(n) access and we impose the restriction that indices is
 increasing (or sort it up front), we can do better than this by only
 doing one pass through coll.

 On Aug 18, 10:46 am, CuppoJava patrickli_2...@hotmail.com wrote:
 The most straight-forward answer I would have given is also:
 (defn slice [indices coll]
   (map #(nth coll %) indices))

 Is there some disadvantage with this approach that I'm not seeing?

-- 
Mark Triggs
mark.h.tri...@gmail.com

--~--~-~--~~~---~--~~
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: Idiom for array slicing

2009-08-18 Thread Mark Triggs

That works nicely, even for infinite sequences, but appears to hang on
to the head:

  user= (split [2000 2001] (repeatedly #(int-array 102400)))
  java.lang.OutOfMemoryError: Java heap space

The map/nth variant has this same problem, unfortunately.  My original
version works around these issues at the expense of being longer and
uglier ;o)

Mark


CuppoJava patrickli_2...@hotmail.com writes:

 I see. Thanks for explaining.

 If speed is an issue, and if you can assume that indices are properly
 sorted in ascending order, I believe this looks like a lazy-reduce
 problem. Clojure has no lazy-reduce (or does it?) so I've written my
 own:

 (defn lazy_reduce [f val coll]
   (lazy-seq
 (if (seq coll)
   (let [val (f val (first coll))]
 (cons val (lazy_reduce f val (rest coll)))

 (defn split [indices coll]
   (map first
(lazy_reduce nthnext coll
  (map - indices (cons 0 indices)

-- 
Mark Triggs
mark.h.tri...@gmail.com

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



Idiom for array slicing

2009-08-17 Thread Mark Triggs

Hi all,

Is there an idiom for what I'm doing below, or does a function already
exist?

(let [vowels (slice abcdefghijklmnopqrstuvwxyz
 0 4 8 14 20)]
  vowels)
  = (\a \e \i \o \u)


A possible implementation:

  (defn slice
Return the items in coll at index positions keys.

(slice \abcdefg\ 0 4 6) = (\\a \\e \\g)
[coll  keys]
(let [keyset (set keys)]
  (for [[idx elt] (indexed coll)
:when (keyset idx)]
elt)))

I often want something like this when picking apart lines from log files
(calling .split on a string, then grabbing certain segments)

Thanks,

Mark

-- 
Mark Triggs
mark.h.tri...@gmail.com

--~--~-~--~~~---~--~~
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: Idiom for array slicing

2009-08-17 Thread Mark Triggs

Thanks all.  So combining a few suggested ideas:

  (defn slice
  Return the items in coll at index positions keys.

  (slice [0 4 6] \abcdefg\) = (\\a \\e \\g)
[keys coll]
(let [max-idx (apply max keys)
  keyset (set keys)]
  (map second
   (filter (fn [[idx _]] (keyset idx))
   (take-while (fn [[idx _]] (= idx max-idx))
   (indexed coll))

This version has the advantage of working on infinite sequences and not
hanging onto the head.  This works as expected:

  (slice [200 201] (repeatedly #(int-array 102400)))

without blowing up the stack or throwing OutOfMemory (on my JVM).

Thanks again,

Mark


Mark Triggs mark.h.tri...@gmail.com writes:

 Hi all,

 Is there an idiom for what I'm doing below, or does a function already
 exist?

 (let [vowels (slice abcdefghijklmnopqrstuvwxyz
  0 4 8 14 20)]
   vowels)
   = (\a \e \i \o \u)


-- 
Mark Triggs
mark.h.tri...@gmail.com

--~--~-~--~~~---~--~~
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: Uncle Bob: bowling meets Clojure

2009-07-21 Thread Mark Triggs

Hi Stu,


Stuart Halloway stuart.hallo...@gmail.com writes:

 Uncle Bob Martin, a very well-respected OO and agile guy, is learning  
 Clojure. He has posted an example [1] and asked for feedback from the  
 Clojure community. I have made my suggestions in code [2] and will be  
 writing them up shortly.

 Would love to see what other folks on this list have to say.

My first version came out rather similar to yours, and then I started
thinking about turning the problem on its head and making the concept of
types of rolls more explicit.  I'm still not sure how I feel about
this, but the line of thinking led me to code like this:

  (ns bowling-game
(:use clojure.contrib.seq-utils))


  (def *roll-types*
   [{:name strike
 :satisfies #(= (first %) 10)
 :consumes 3
 :advances 1}

{:name spare
 :satisfies #(= (apply + (take 2 %))
10)
 :consumes 3
 :advances 2}

{:name regular (underachieving?)
 :satisfies (constantly true)
 :consumes 2
 :advances 2}])


  (defn roll-type [rolls]
(find-first #((:satisfies %) rolls)
*roll-types*))


  (defn frames [rolls]
(when (seq rolls)
  (let [{:keys [consumes advances]} (roll-type rolls)]
(cons (take consumes rolls)
  (frames (drop advances rolls))


  (defn score-game [rolls]
(reduce + (map #(reduce + %)
   (take 10 (group-frames rolls)


Cheers,

Mark

-- 
Mark Triggs
mark.h.tri...@gmail.com

--~--~-~--~~~---~--~~
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: Algorithm help

2009-07-17 Thread Mark Triggs

Heheh, three times slower but gives the wrong answer--maybe not a
great trade-off :o)

I'd misread the way the last if statements work in the Python
version.  I modified mine to read:

(defn backtrack-all [c x y i j]
  (cond (or (zero? i) (zero? j))
#{}

(= (get x (dec i)) (get y (dec j)))
(set (map #(str % (get x (dec i)))
  (backtrack-all c x y (dec i) (dec j

:else
(set (concat (when (= (get-in c [i (dec j)])
   (get-in c [(dec i) j]))
   (backtrack-all c x y i (dec j)))
 (when (= (get-in c [(dec i) j])
   (get-in c [i (dec j)]))
   (backtrack-all c x y (dec i) j))

I'd mistakenly assumed that those last two conditionals were mutually
exclusive, but they're not.

Cheers,

Mark

On Jul 17, 7:07 pm, martin_clausen martin.clau...@gmail.com wrote:
 Thanks. Your code is definitely much more idiomatic Clojure - and 3X
 faster. The lcs function does exactly what it is suppose to, but the
 backtrack-all function only returns the first LCS found(for the
 strings AATCC ACACG = (ACC), whereas the Python version returns
 all the LCSes found (for the same strings = set(['ACC', 'AAC'])). I
 have tried to find out why this is, but cannot identify the cause.

 On Jul 17, 12:16 am, Mark Triggs mark.h.tri...@gmail.com wrote:

  Hi there,

  I had a bit of a go at converting the Python version into Clojure and
  removed the need to mutate an array.  Because the 'lcs' function was
  basically just mapping over a list of i/j pairs and accumulating the
  resulting matrix, it seemed like a good candidate for reduce:

  (defn lcs [x y]
    (let [m (count x)
          n (count y)]
      (reduce (fn [c [i j]]
                (if (= (get x (dec i))
                       (get y (dec j)))
                  (assoc-in c [i j] (inc (get-in c [(dec i) (dec j)])))
                  (assoc-in c [i j] (max (get-in c [i (dec j)])
                                         (get-in c [(dec i) j])
              (vec (replicate (inc n)
                              (vec (replicate (inc m)
                                              0
              (for [i (range 1 (inc m))
                    j (range 1 (inc n))]
                [i j]

  Then, 'backtrack-all' is pretty much a straight translation of the
  Python one, but with tail recursion where possible:

  (defn backtrack-all [c x y i j]
    (cond (or (zero? i) (zero? j))
          #{}

          (= (get x (dec i)) (get y (dec j)))
          (set (map #(str % (get x (dec i)))
                    (backtrack-all c x y (dec i) (dec j

          (= (get-in c [i (dec j)])
              (get-in c [(dec i) j]))
          (recur c x y i (dec j))

          (= (get-in c [(dec i) j])
              (get-in c [i (dec j)]))
          (recur c x y (dec i) j)))

  Mostly untested ;o)

  Cheers,

  Mark

  On Jul 17, 6:57 am, martin_clausen martin.clau...@gmail.com wrote:

   Can anybody give me some hints on how to translate 
   this:http://bit.ly/lcs_py
   (the backTrackAll function) from Python into Clojure? I have a pasted
   my attempt here:http://paste.lisp.org/+1SL7, but it doesn't work. For
   completeness I have included the functions required to test the
   traceback-all-lcs function and my traceback-lcs function (that
   works :-)).

   I cannot figure out if it is the list comprehension that is wrong or
   my use of cons or some immutability thing that is tricking me.
--~--~-~--~~~---~--~~
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: Algorithm help

2009-07-16 Thread Mark Triggs

Hi there,

I had a bit of a go at converting the Python version into Clojure and
removed the need to mutate an array.  Because the 'lcs' function was
basically just mapping over a list of i/j pairs and accumulating the
resulting matrix, it seemed like a good candidate for reduce:

(defn lcs [x y]
  (let [m (count x)
n (count y)]
(reduce (fn [c [i j]]
  (if (= (get x (dec i))
 (get y (dec j)))
(assoc-in c [i j] (inc (get-in c [(dec i) (dec j)])))
(assoc-in c [i j] (max (get-in c [i (dec j)])
   (get-in c [(dec i) j])
(vec (replicate (inc n)
(vec (replicate (inc m)
0
(for [i (range 1 (inc m))
  j (range 1 (inc n))]
  [i j]

Then, 'backtrack-all' is pretty much a straight translation of the
Python one, but with tail recursion where possible:

(defn backtrack-all [c x y i j]
  (cond (or (zero? i) (zero? j))
#{}

(= (get x (dec i)) (get y (dec j)))
(set (map #(str % (get x (dec i)))
  (backtrack-all c x y (dec i) (dec j

(= (get-in c [i (dec j)])
(get-in c [(dec i) j]))
(recur c x y i (dec j))

(= (get-in c [(dec i) j])
(get-in c [i (dec j)]))
(recur c x y (dec i) j)))

Mostly untested ;o)

Cheers,

Mark


On Jul 17, 6:57 am, martin_clausen martin.clau...@gmail.com wrote:
 Can anybody give me some hints on how to translate this:http://bit.ly/lcs_py
 (the backTrackAll function) from Python into Clojure? I have a pasted
 my attempt here:http://paste.lisp.org/+1SL7, but it doesn't work. For
 completeness I have included the functions required to test the
 traceback-all-lcs function and my traceback-lcs function (that
 works :-)).

 I cannot figure out if it is the list comprehension that is wrong or
 my use of cons or some immutability thing that is tricking me.
--~--~-~--~~~---~--~~
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: Adding type hint causes compiler error

2009-07-05 Thread Mark Triggs

Hi Phil,

Part of me hopes there's a nicer way of doing this, but I was able to
get it working using:

(defn bi-get-pixels
  [#^BufferedImage bi]
  (let [raster (.getData bi)
pixels (.getPixels raster 0 0 (.getWidth bi) (.getHeight bi)
   (cast (Class/forName [I) nil))]
(vec pixels)))

Cheers,

Mark


On Jul 5, 10:18 pm, philip.hazel...@gmail.com
philip.hazel...@gmail.com wrote:
 Hi,

 The following code works as expected:

 (import 'javax.imageio.ImageIO 'java.io.File
 'java.awt.image.BufferedImage)
 (defn bi-get-pixels
   [bi]
   (vec (.. bi (getData) (getPixels 0 0 (.getWidth bi) (.getHeight bi)
 nil
 (bi-get-pixels (. ImageIO read (File. /home/phil/prog/small-
 test.png)))

 But if *warn-on-reflection* is true, it generates four warnings. If we
 try to shut it up with a type hint:

 (defn bi-get-pixels
   [#^BufferedImage bi]
   (vec (.. bi (getData) (getPixels 0 0 (.getWidth bi) (.getHeight bi)
 nil

 Exception in thread main java.lang.IllegalArgumentException: More
 than one matching method found: getPixels (imagio-test.clj:7)
         at clojure.lang.Compiler.analyzeSeq(Compiler.java:4558)
 ...
 Caused by: java.lang.IllegalArgumentException: More than one matching
 method found: getPixels
         at clojure.lang.Compiler.getMatchingParams(Compiler.java:2122)
         at clojure.lang.Compiler$InstanceMethodExpr.init
 (Compiler.java:1159)
         at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:
 810)
         at clojure.lang.Compiler.analyzeSeq(Compiler.java:4551)
         ... 34 more

 The problem here is that getPixels has three forms: 
 (http://java.sun.com/j2se/1.4.2/docs/api/java/awt/image/Raster.html)
  double[]       getPixels(int x, int y, int w, int h, double[] dArray)
           Returns a double array containing all samples for a
 rectangle of pixels, one sample per array element.
  float[]        getPixels(int x, int y, int w, int h, float[] fArray)
           Returns a float array containing all samples for a rectangle
 of pixels, one sample per array element.
  int[]  getPixels(int x, int y, int w, int h, int[] iArray)
           Returns an int array containing all samples for a rectangle
 of pixels, one sample per array element.

 In each case, if the final argument is NULL it is ignored, and if not
 the array is populated with the return data from the call (generating
 an error if it's not large enough).

 Is it possible to specify which invocation of getPixels I intend
 without passing an array? I've tried putting #^ints in some likely-
 looking places, but nil can't be type-hinted and the others seem to
 have no effect. I've also tried splitting the .. up:

 (defn bi-get-pixels
   [#^BufferedImage bi]
   (let [rast (.getData bi)
         #^ints pi (.getPixels rast 0 0 (.getWidth bi) (.getHeight bi) nil)]
     pi))

 But this doesn't work either. I could do manual reflection on Raster
 to get the correct method and .invoke it, but that seems far more
 complicated than necessary. Any other ideas?

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



SLIME/elisp hack to generate import lines

2009-04-25 Thread Mark Triggs

Hi all,

I just thought I'd write to share a terrible (but maybe useful!) hack
for SLIME.  I've written some code that sniffs around the classpath to
find libraries matching some regexp, then inserts the appropriate
`import' sexps into the current buffer.  For example:

  M-x clj-import [RET] IndexWriter [RET]

inserts (for my classpath):

  (import '(org.apache.lucene.index IndexWriter IndexWriter
$MaxFieldLength))

Yep, I'm *that* lazy.  I've put the code here:

  http://dishevelled.net/Generating-Clojure-import-lines-using-SLIME.html

Cheers,

Mark

--~--~-~--~~~---~--~~
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
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: Nested loops

2009-04-04 Thread Mark Triggs

Hi David,

Quite a few times when I've felt the need for this sort of thing I've
found that laziness comes to the rescue.  Would something like this
sort of approach work for you?

(defn possibilities [word pos]
  All variations of `word' with letters from 'a' to 'z' inserted at
`pos'
  (let [[beg end] (split-at pos word)
letters (map char (range (int \a) (inc (int \z]
(map #(apply str (concat beg [%] end)) letters)))

(defn all-possibilities [word]
  (for [n (range (inc (count word)))
pos (possibilities word n)]
pos))

;; Since all-possibilities produces a lazy seq we don't need short
circuiting anyway...
(some #(binary-search word) (all-possibilities hello))

Cheers,

Mark


On Apr 5, 1:26 pm, David Sletten da...@bosatsu.net wrote:
 I'm working on a spell checker that attempts to suggest corrections  
 from a given dictionary. One of the heuristics is to see if inserting  
 a character at each point in the given string results in a recognized  
 word. So I have an outer loop that moves across each position in the  
 string and an inner loop that tests a-z at that point. In Common Lisp  
 I use this:
 (defun word-insertion (s)
    (let ((s1 (make-string (1+ (length s)   ; Copy the input and  
 make room for an extra char
      (setf (subseq s1 1 (length s1)) s)
      (dotimes (i (length s1) nil)                      ; Outer loop
        (unless (zerop i) (setf (char s1 (1- i)) (char s (1- i
        (dotimes (j (1+ (- (char-code #\z) (char-code #\a   ;  
 Inner loop
          (setf (char s1 i) (code-char (+ j (char-code #\a
          (let ((index (binary-search s1)))     ; Check in the  
 dictionary for a match
            (when index (return-from word-insertion index )))    ;  
 Done if match found

 The main point is that I can use two DOTIMES forms, one nested inside  
 the other, and I can exit either at any point. I actually exit the  
 entire function as soon as I find a match via RETURN-FROM.

 Clojure has 'dotimes', but from what I understand there is no way to  
 exit prematurely?

 The obvious alternative is to nest a couple of 'loop' forms:
 (defn g [p q]
    (loop [i 0]
      (if (= i p)
        nil
        (do
          (loop [j 0]
            (if (= j q)
              nil
              (do
                (prn (list i j))
                (recur (inc j )
          (recur (inc i ))

 The loop/recur pairs seem to establish outer and inner recursion  
 points (I can't really tell from the macro expansion), and this  
 function behaves as expected. This approach appears to be equivalent  
 to something like this:
 (defn f [p q]
    (letfn [(outer [i]
              (if (= i p)
                nil
                (do
                  (inner i 0)
                  (outer (inc i )
            (inner [i j]
              (if (= j q)
                nil
                (do
                  (prn (list i j))
                  (inner i (inc j )]
      (outer 0)))

 Again the important thing is that I can terminate the inner loop  
 based on my own condition. However, it seems that in the outer loop I  
 have to capture the value of the inner loop directly. I can't simply  
 leave both loops:
 (defn word-insertion [s]
    (let [s1 (make-array Character/TYPE (inc (count s)))]
      (System/arraycopy (.toCharArray s) 0 s1 1 (count s))
      (loop [i 0]
        (if (= i (count s1))
          nil
          (do
            (when-not (zero? i)
              (aset s1 (dec i) (nth s (dec i
            (let [match (loop [j 0]
                          (if (= j (inc (- (int \z) (int \a
                            nil
                            (do
                              (aset s1 i (char (+ j (int \a
                              (let [match (binary-search (String. s1))]
                                (if match
                                  match
                                  (recur (inc j )))]
              (if match
                match
                (recur (inc i  )

 One other version I considered makes due with a single 'loop', but  
 this is pretty convoluted:
 (defn word-insertion [s]
    (let [s1 (make-array Character/TYPE (inc (count s)))]
      (System/arraycopy (.toCharArray s) 0 s1 1 (count s))
      (loop [i 0
             j 0]
        (when (and (not (zero? i))
                   (zero? j))
          (aset s1 (dec i) (nth s (dec i
        (cond (= i (count s1)) nil
              (= j (inc (- (int \z) (int \a (recur (inc i) 0)
              :else (do
                      (aset s1 i (char (+ j (int \a
                      (let [match (binary-search (String. s1))]
                        (if match
                          match
                          (recur i (inc j  )

 The one nice thing about this is I can terminate the entire loop and  
 return a value in one step. Otherwise the logic is a mess.

 Any suggestions out there?

 Aloha,
 David Sletten

Re: Quick slime/emacs questions

2009-03-29 Thread Mark Triggs

Something like this in your ~/.emacs might do the job:

  (define-key global-map (kbd C-x C-b)
(lambda ()
(interactive)
(select-window (call-interactively 'list-buffers

Cheers,

Mark


On Mar 30, 7:41 am, Mark Engelberg mark.engelb...@gmail.com wrote:
 When I have two windows open, and hit C-x-C-b, it pops up a list of
 buffers in the OTHER window from where the current focus is.  Any idea
 why it's doing that, and how I can alter the behavior so it pops up
 the list of buffers in the current window?

 Also, where can I look up the names of various commands to rebind to
 different keys?  For example, I want to remap C-s to do what C-x-C-s
 currently does, and I wan to remap C-f to do what C-s currently does,
 to make behavior more consistent with other programs I use.  (After
 using emacs for a while, I inevitably find myself hitting C-x-C-s to
 save in other programs :) )

 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
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: Calling `str' on a LazySeq

2009-03-22 Thread Mark Triggs

Hi David,

On Mar 22, 5:01 pm, David Sletten da...@bosatsu.net wrote:
 On Mar 21, 2009, at 1:44 PM, Mark Triggs wrote:

    user= (str (filter even? (range 1 10)))
    clojure.lang.lazy...@f1005

  Previously this would readably print the contents of the seq and some
  of my code was relying on this.  Obviously it's not difficult to call
  `prn-str' myself, but I just wondered if this change was made
  consciously.

 According to the documentation for 'str':
 With one arg x, returns x.toString().

 So it looks like toString() on a sequence used to return its contents  
 and now doesn't. However, rather than relying on this behavior what  
 you probably should be doing is using 'apply':
 (apply str (filter even? (range 1 10))) = 2468

 If you want commas between those elements, use 'interpose':
 (apply str (interpose ,  (filter even? (range 1 10 = 2, 4, 6, 8

Yep, that's fine.  In my case I was actually relying on the fact that
`str' was effectively doing a `prn-str' because I would later read it
back using `read-string' elsewhere.  Calling `prn-str' explicitly
isn't a problem--I just thought I'd mention that the semantics have
now changed a little.

Thanks,

Mark
--~--~-~--~~~---~--~~
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
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: doall vs. dorun

2009-01-20 Thread Mark Triggs

In addition to what others have said, I also tend to use doall when
working with agent actions that return sequences (i.e. to force any
computation to happen in the agent's thread and not in the caller's)

Cheers,

Mark

On Wed, Jan 21, 2009 at 7:32 AM, Mark Volkmann
r.mark.volkm...@gmail.com wrote:

 Can someone describe a situation where it is preferable to use doall
 instead of dorun? I see in the documentation that it retains the head
 and returns it, thus causing the entire seq to reside in memory at one
 time, but I'm not sure why I'd want that.

 --
 R. Mark Volkmann
 Object Computing, Inc.

 


--~--~-~--~~~---~--~~
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
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: java.lang.IncompatibleClassChangeError: [class] and [inner class] disagree on InnerClasses attribute

2009-01-13 Thread Mark Triggs

Aha!  I notice that this problem goes away if I run the JVM the way
I'm supposed to (with -cp lucene-core.xxx.jar) instead of using (add-
classpath ...) to load the jar in the first place.  This probably
isn't a big deal, then :o)

Thanks,

Mark

On Jan 13, 11:06 am, Mark Triggs mark.h.tri...@gmail.com wrote:
 Hi all,

 I've just been fiddling with Lucene indexing from Clojure, and wanted
 to
 access a static field of this inner class:

  http://lucene.apache.org/java/2_4_0/api/org/apache/lucene/index/Index...

 I'm importing IndexWriter$MaxFieldLength with no problems, but
 attempts
 to eval:

   IndexWriter$MaxFieldLength/UNLIMITED

 or

   (. IndexWriter$MaxFieldLength UNLIMITED)

 both yield the following exception:

   java.lang.IncompatibleClassChangeError:
   org.apache.lucene.index.IndexWriter and
   org.apache.lucene.index.IndexWriter$MaxFieldLength disagree on
   InnerClasses attribute (NO_SOURCE_FILE:0) [Thrown class
   clojure.lang.Compiler$CompilerException]

 I'm running SVN r1205.  Am I doing something wrong here?

 Thanks,

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



java.lang.IncompatibleClassChangeError: [class] and [inner class] disagree on InnerClasses attribute

2009-01-12 Thread Mark Triggs

Hi all,

I've just been fiddling with Lucene indexing from Clojure, and wanted
to
access a static field of this inner class:

  
http://lucene.apache.org/java/2_4_0/api/org/apache/lucene/index/IndexWriter.MaxFieldLength.html

I'm importing IndexWriter$MaxFieldLength with no problems, but
attempts
to eval:

  IndexWriter$MaxFieldLength/UNLIMITED

or

  (. IndexWriter$MaxFieldLength UNLIMITED)

both yield the following exception:

  java.lang.IncompatibleClassChangeError:
  org.apache.lucene.index.IndexWriter and
  org.apache.lucene.index.IndexWriter$MaxFieldLength disagree on
  InnerClasses attribute (NO_SOURCE_FILE:0) [Thrown class
  clojure.lang.Compiler$CompilerException]

I'm running SVN r1205.  Am I doing something wrong here?

Thanks,

Mark

--~--~-~--~~~---~--~~
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
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 does - mean?

2009-01-11 Thread Mark Triggs

I've also found this useful for accessing members in nested maps.  For
example:

  (let [me {:person {:name {:first Mark
:last Triggs}
 :email mark.h.tri...@gmail.com}}]
(- me :person :name :first))

  = Mark

On Jan 12, 1:04 pm, kkw kevin.k@gmail.com wrote:
 One use I've found for - (though there are others I haven't come to
 appreciate yet) is when I have something like:
 (f1 (f2 (f3 (f4 x

 which can be re-written as
 (- x f4 f3 f2 f1)

 I find the latter expression easier to read.

 Kev

 On Dec 30 2008, 2:49 pm, wubbie sunj...@gmail.com wrote:

  Very criptic for newbie.
  What  does Threads the expr through the forms. mean?
  Does it create a thread to execute?

  thanks
  sun

  On Dec 29, 10:07 pm, Paul Barry pauljbar...@gmail.com wrote:

   You can look up the documentation for a function/macro interactively
   from the repl:

   user= (doc -)
   -
   clojure.core/-
   ([x form] [x form  more])
   Macro
     Threads the expr through the forms. Inserts x as the
     second item in the first form, making a list of it if it is not a
     list already. If there are more forms, inserts the first form as the
     second item in second form, etc.
   nil

   On Dec 29, 8:27 pm, wubbie sunj...@gmail.com wrote:

Hi all,

Looking intoants.clj, I came across
(defn place [[x y]]
  (- world (nth x) (nth y)))

What - mean here?

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



Memory usage when iterating over lazy sequences

2008-10-31 Thread Mark Triggs

Hi all,

I'm just getting started with Clojure, and I've got a bit of a
beginner's question regarding memory usage of lazy sequences.

I have an array of data that is too big to fit in memory, so I thought I
would be clever and process it in manageable-sized chunks.  My instinct
was to do this using loop/recur using 'take' to bite off the next chunk,
and 'drop' to give me the remainder for the next recursive call.  Here's
a contrived example:


  ;; Process the list one chunk at a time 
  (defn do-something [biglist]
(loop [rest (drop 1000 biglist)]
  (when rest
(doall (take 1000 rest))
(recur (drop 1000 rest)


  ;; Lazily calculate our big data set and pass it along for processing 
  (do
(do-something
 (map (fn [n] (make-array java.lang.Character 10240))
  (range 0 10)))
nil)


When I ran my code it very quickly ran out of memory and fell over.
After thinking about it for a while I've realised it must be because my
'do-something' function call is hanging on to the head of the list, so
as its elements are realised and cached it gradually eats up all my
memory.

Assuming my diagnosis is right, is there some sort of idiomatic way of
dealing with this sort of issue?  I suppose that if the JVM allowed for
true tail recursion then this problem wouldn't arise?

Many thanks,

Mark

-- 
Mark Triggs
[EMAIL PROTECTED]

--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Memory usage when iterating over lazy sequences

2008-10-31 Thread Mark Triggs

On Oct 31, 1:57 pm, Mark Triggs [EMAIL PROTECTED] wrote:

 When I ran my code it very quickly ran out of memory and fell over.
 After thinking about it for a while I've realised it must be because my
 'do-something' function call is hanging on to the head of the list, so
 as its elements are realised and cached it gradually eats up all my
 memory.

Answering my own question, using the function itself as the recur
target does exactly what I want:

  ;; Process the list one chunk at a time
  (defn do-something [biglist]
(when biglist
  (doall (take 1000 biglist))
  (recur (drop 1000 biglist

I guess I should have tried it instead of assuming it wouldn't work.
Please excuse my talking to myself :o)

Cheers,

Mark
--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---