hello,

samppi a écrit :
> I tried asking about this yesterday, but it seems like I expressed my
> problem poorly. Anyways, here's another shot. :)
>
> (declare value)
>
> (def array (conc array-start value array-sep value array-end))
>
> (def value (alt array bit))
>   

You can get your code to work by writing:

(declare value)
(def array (conc array-start #'value array-sep #'value array-end))
(def value (alt array bit))


#'value introduces an indirection by returning the var and not the 
functions (and a var proxies calls to its current value) but this 
indirection is mutable.




You can also try to use delays:
(defn conc [& subrules]
  (fn [tokens]
    (loop [subrule-queue (map force subrules), remaining-tokens (seq 
tokens), products []] ; force (potentially) delayed rules
      (if (nil? subrule-queue)
        [products remaining-tokens]
        (let [[subrule-products subrule-remainder :as subrule-result]
              ((first subrule-queue) remaining-tokens)]
          (when-not (nil? subrule-result)
            (recur (rest subrule-queue) subrule-remainder
                   (conj products subrule-products))))))))

(defn alt [& subrules]
  (fn [tokens]
    (some #((force %) tokens) subrules))) ; added force

Here a subrule is either a function or a delay on a function:

(declare value)
(def array (delay (conc array-start value array-sep value array-end)))
(def value (alt array bit))

samppi=> (value (seq "[0,0]"))
[[\[ \0 \, \0 \]] nil]
samppi=> (array (seq "[0,0]"))
java.lang.ClassCastException: clojure.lang.Delay cannot be cast to 
clojure.lang.IFn (NO_SOURCE_FILE:0)
samppi=> ((force array) (seq "[0,0]"))
[[\[ \0 \, \0 \]] nil]

You may have to write a "call-rule" helper function to force the rule 
before calling it.




But, without resorting to macros, You can also do:
(defn conc [tokens & subrules]
  (loop [subrule-queue (seq subrules), remaining-tokens (seq tokens), 
products []]
    (if (nil? subrule-queue)
      [products remaining-tokens]
      (let [[subrule-products subrule-remainder :as subrule-result]
            ((first subrule-queue) remaining-tokens)]
        (when-not (nil? subrule-result)
          (recur (rest subrule-queue) subrule-remainder
                 (conj products subrule-products)))))))

(defn alt [tokens & subrules]
  (some #(% tokens) subrules))

(declare value)
(defn array [tokens]
  (conc tokens array-start value array-sep value array-end))
(defn value [tokens]
  (alt tokens array bit))

(But really it's what a macro should produce :-()


Hope this help.

Christophe



-- 
Professional: http://cgrand.net/ (fr)
On Clojure: http://clj-me.blogspot.com/ (en)



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

Reply via email to