All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.jlangch.venice.old.walk.venice Maven / Gradle / Ivy

There is a newer version: 1.12.34
Show newest version
;;;;   __    __         _
;;;;   \ \  / /__ _ __ (_) ___ ___
;;;;    \ \/ / _ \ '_ \| |/ __/ _ \
;;;;     \  /  __/ | | | | (_|  __/
;;;;      \/ \___|_| |_|_|\___\___|
;;;;
;;;;
;;;; Copyright 2017-2024 Venice
;;;;
;;;; Licensed under the Apache License, Version 2.0 (the "License");
;;;; you may not use this file except in compliance with the License.
;;;; You may obtain a copy of the License at
;;;;
;;;;     http://www.apache.org/licenses/LICENSE-2.0
;;;;
;;;; Unless required by applicable law or agreed to in writing, software
;;;; distributed under the License is distributed on an "AS IS" BASIS,
;;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;;;; See the License for the specific language governing permissions and
;;;; limitations under the License.

;;;; Venice walk functions

;;;; Thanks to Stuart Sierra and his clojure walk project
;;;; (https://github.com/clojure/clojure/blob/master/src/clj/clojure/walk.clj).
;;;; Venice's walk builds heavily on Stuart Sierra's work.



(ns walk)

(defn-
  ^{ :arglists '("(walk inner outer form)")
     :doc """
          Traverses form, an arbitrary data structure. inner and outer are
          functions. Applies inner to each element of form, building up a
          data structure of the same type, then applies outer to the result.

          Do not call this function directly use walk/postwalk or
          walk/prewalk instead.
          """ }

  walk [inner outer form]

  (cond
    (list? form) (outer (apply list (map inner form)))
    (map-entry? form) (outer (map-entry (inner (key form)) (inner (val form))))
    (coll? form) (outer (into (empty form) (map inner form)))
    :else (outer form)))


(defn
  ^{ :arglists '("(postwalk f form)")
     :doc """
          Performs a depth-first, post-order traversal of form. Calls f on
          each sub-form, uses f's return value in place of the original.
          """
     :examples (list
          """
          (walk/postwalk (fn [x] (println "Walked:" (pr-str x)) x)
                         '(1 2 {:a 1 :b 2}))
          """) }

  postwalk [f form]

  (walk/walk (partial postwalk f) f form))


(defn
  ^{ :arglists '("(prewalk f form)")
     :doc """
          Performs a depth-last, pre-order traversal of form. Calls f on
          each sub-form, uses f's return value in place of the original.
          """
     :examples (list
          """
          (walk/prewalk (fn [x] (println "Walked:" (pr-str x)) x)
                         '(1 2 {:a 1 :b 2}))
          """) }

  prewalk [f form]

  (walk/walk (partial prewalk f) identity (f form)))


(defn
  ^{ :arglists '("(postwalk-dump form)")
     :doc """
          Demonstrates the behavior of postwalk by printing each form
          as it is walked. Returns the form.
          """
     :examples (list "(walk/postwalk-dump '(1 2 {:a 1 :b 2}))") }

  postwalk-dump [form]

  (walk/postwalk (fn [x] (println "Walked:" (pr-str x)) x) form))


(defn
  ^{ :arglists '("(prewalk-dump form)")
     :doc """
          Demonstrates the behavior of prewalk by printing each form
          as it is walked. Returns the form.
          """
     :examples (list "(walk/prewalk-dump '(1 2 {:a 1 :b 2}))") }

  prewalk-dump [form]

  (walk/prewalk (fn [x] (println "Walked:" (pr-str x)) x) form))


(defn
  ^{ :arglists '("(keywordize-keys form)")
     :doc "Recursively transforms all map keys from strings to keywords."
     :examples (list """(walk/keywordize-keys '(1 2 {"a" 1 "b" 2}))""") }

  keywordize-keys [form]

  (let [f (fn [[k v]] (if (string? k) [(keyword k) v] [k v]))]
    ;; only apply to maps
    (walk/postwalk (fn [x] (if (map? x) (into {} (map f x)) x)) form)))


(defn
  ^{ :arglists '("(stringify-keys form)")
     :doc "Recursively transforms all map keys from keywords to strings."
     :examples (list """(walk/stringify-keys '(1 2 {:a 1 :b 2}))""") }

  stringify-keys [form]

  (let [f (fn [[k v]] (if (keyword? k) [(name k) v] [k v]))]
    ;; only apply to maps
    (walk/postwalk (fn [x] (if (map? x) (into {} (map f x)) x)) form)))


(defn
  ^{ :arglists '("(prewalk-replace key-map form)")
     :doc """
          Recursively transforms form by replacing keys in key-map with
          their values. Does replacement at the root of the tree first.
          """
     :examples (list
          "(walk/prewalk-replace {:a :A :b :B} '(1 2 :a :b))",
          "(walk/prewalk-replace {:a :A :b :B} '(1 2 {:a 1 :b 2}))" ) }

  prewalk-replace [key-map form]

  (walk/prewalk (fn [x] (if (contains? key-map x) (key-map x) x)) form))


(defn
  ^{ :arglists '("(postwalk-replace key-map form)")
     :doc """
          Recursively transforms form by replacing keys in key-map with
          their values. Does replacement at the leaves of the tree first.
          """
     :examples (list
          "(walk/postwalk-replace {:a :A :b :B} '(1 2 :a :b))",
          "(walk/postwalk-replace {:a :A :b :B} '(1 2 {:a 1 :b 2}))" ) }

  postwalk-replace [key-map form]

  (walk/postwalk (fn [x] (if (contains? key-map x) (key-map x) x)) form))


(defn
  ^{ :arglists '("(macroexpand-all form)")
     :doc "Recursively expands all macros in the form."
     :examples (list
          "(walk/macroexpand-all '(and true true))",
          "(walk/macroexpand-all '(and true (or true false) true))"
          "(walk/macroexpand-all '(let [n 5] (cond (< n 0) -1 (> n 0) 1 :else 0)))" ) }

  walk/macroexpand-all [form]

  (walk/prewalk (fn [x] (if (list? x) (macroexpand x) x)) form))




© 2015 - 2024 Weber Informatics LLC | Privacy Policy