Giter VIP home page Giter VIP logo

yang's Introduction

yang

.. of Clojure's yin

<! release <! clojars

why

.. not to carry often useful functions from project to project

some of these have a faint "missing from Clojure" feeling
some just very useful but have no such feeling

one thing they all have in common: no external dependencies

show me

ok. here are a few examples, there are many more inside:

lang

=> (require '[yang.lang :as l])

fn on every key in a map:

=> (l/fmk {"a" 42 "b" 34} keyword)
{:a 42, :b 34}

fn on every value in a map:

=> (l/fmv {"a" 42 "b" 34} inc)
{"a" 43, "b" 35}

dissoc-in.. oh, yea

=> (l/dissoc-in {:foo {:bar {:a 42 :b "don't need this"}}}
                [:foo :bar :b])
{:foo {:bar {:a 42}}}

tasty sequential UUIDs:

=> (repeatedly 4 #(l/squuid))
(#uuid "5f62baed-553c-49a1-ad85-2b387634e773"
 #uuid "5f62baed-93d2-4e9a-bcd1-beedcaa7e1ee"
 #uuid "5f62baed-b730-44f6-946f-d55b56893121"
 #uuid "5f62baed-d45d-49be-9034-c661fe8069f1")

templating:

=> (l/rebrace "{{child}}, I am your {{parent}}"
              {:child "Luke" :parent "father"})
"Luke, I am your father"

make it Clojure:

=> (l/dash-keys {:a_foo 42 :b_bar 34})
{:a-foo 42, :b-bar 34}

thread and on functions:

=> (l/and-> 5 number? pos?)
true
=> (l/and-> nil number? pos?)
false

tame those namespaced keys:

=> (l/group-by-ns {:a/one :a-one :b/one :b-one :a/two :a-two :b/two :b-two})
{:a {:one :a-one, :two :a-two},
 :b {:one :b-one, :two :b-two}}

be a database, do da joins:

=> (l/join [{:a 20, :b 34} {:a 31, :b 27} {:a 28, :b 42}]
           [{:a 31, :b 27} {:a 12, :b 4} {:a 28, :b 42}]
           :a)
[{:a 31, :b 27} {:a 28, :b 42}]

merge maps, but merge it deep:

=> (l/merge-maps {:a {:b {:c 12}} :d 21 :z 34}
                 {:a {:b {:c 42}} :d 25})
{:a {:b {:c 42}}, :d 25, :z 34}

gzip / gunzip edn:

=> (l/gzip-edn {:a 42 :b 28 :c [{:z #{:a :b 42}}]})
#object["[B" 0x2aafa84f "[B@2aafa84f"]

=> (l/gunzip-edn *1)
{:a 42, :b 28, :c [{:z #{:b 42 :a}}]}

time

=> (require '[yang.time :as t])

sorting (java.time) instants:

=> (def dates [{:date (t/now-utc)} {:date (t/now-utc)} {:date (t/now-utc)}])
#'user/dates

;; DESC in time
=> (sort-by :date t/time> dates)
({:date #object[java.time.Instant 0x2f75a9b1 "2020-07-13T19:56:11.794186Z"]}
 {:date #object[java.time.Instant 0x9cc0505 "2020-07-13T19:56:11.794174Z"]}
 {:date #object[java.time.Instant 0x26cdd4af "2020-07-13T19:56:11.794141Z"]})

measure things:

=> (t/measure "42 sum" println (reduce + (range 42)))
"42 sum" took: 79,319 nanos
861

codec

=> (require '[yang.codec :as c])

base64 is just too common:

=> (c/base64-encode (-> "distance from you to mars is 69,561,042" .getBytes))
"ZGlzdGFuY2UgZnJvbSB5b3UgdG8gbWFycyBpcyA2OSw1NjEsMDQy"

=> (-> "ZGlzdGFuY2UgZnJvbSB5b3UgdG8gbWFycyBpcyA2OSw1NjEsMDQy"
       c/base64-decode
       String.)
"distance from you to mars is 69,561,042"

network

=> (require '[yang.network :as n])

name of da host:

=> n/hostname
"tweedledee/10.143.34.42"

destructure URIs:

=> (n/uri->map "postgresql://192.168.10.42:4242/planets")

{:path "/planets",
 :user-info nil,
 :fragment nil,
 :authority "192.168.10.42:4242",
 :port 4242,
 :host "192.168.10.42",
 :scheme-specific-part "//192.168.10.42:4242/planets",
 :query nil,
 :scheme "postgresql"}

even if URIs are JDBC:

=> (n/jdbc-uri->map "jdbc:postgresql://192.168.10.42:4242/planets")

{:path "/planets",
 :user-info nil,
 :fragment nil,
 :authority "192.168.10.42:4242",
 :port 4242,
 :dbname "planets",
 :host "192.168.10.42",
 :scheme-specific-part "//192.168.10.42:4242/planets",
 :query nil,
 :scheme "postgresql"}

schedule

=> (require '[yang.scheduler :as s])

schedule functions to run on intervals:

=> (def hh (s/every 1000 #(println "hey humans!")))
#'user/hh

hey humans!
hey humans!
hey humans!
hey humans!
hey humans!
hey humans!
hey humans!
hey humans!
hey humans!

user=> (s/stop hh)
true

start/stop a farm of threads running a function:

=> (defn f []
     (println (s/thread-name))
     (Thread/sleep 5000))
#'user/f

;; schedule a function "f" to run with 42 threads:

=> (def farm (s/run-fun f 42))
yang-runner-0
yang-runner-1
yang-runner-2
...
yang-runner-39
yang-runner-40
yang-runner-41

;; stop the farm of threads from calling "f":

=> (-> farm :running? (reset! false))
false

=> farm
{:pool ThreadPoolExecutor [Running, pool size = 42, active threads = 0, queued tasks = 0, completed tasks = 42]"],
 :running? #atom[false 0x340b4f07]}

schedule to run a function n times (on a different thread):

=> (sc/ftimes 5 #(println "lotery numbers are:" (repeatedly 5 (fn [] (rand-int 42)))))
lotery numbers are: (31 2 27 29 28)
lotery numbers are: (3 28 40 15 1)
lotery numbers are: (13 26 18 19 21)
lotery numbers are: (37 18 18 23 17)
lotery numbers are: (7 16 20 35 8)

exceptions

=> (require '[yang.exception :as ex])

make sure no exception is left behind:

=> (ex/set-default-exception-handler)

io

=> (require '[yang.io :as io])

read files for what they are.. bytes:

=> (io/file->bytes "src/yang/io.clj")
#object["[B" 0x6339e604 "[B@6339e604"]

java

from Java

jshell> import tolitius.Yang;

jshell> var m = Map.of("foo", 42, "nested", Map.of("bar", 34), "zoo", 28)
m ==> {foo=42, nested={bar=34}, zoo=28}

jshell> var edn = Yang.mapToEdn(m)
edn ==> {:foo 42, :nested {:bar 34}, :zoo 28}

// so now it can be injected in any Clojure lib that is called from Java and expects EDN
composing Java and Clojure functions
jshell> import tolitius.Yang;
        import com.google.common.base.CaseFormat;
        import clojure.java.api.Clojure;

        var require = Clojure.var("clojure.core", "require");
        var kw = Clojure.var("clojure.core", "keyword");
        var comp = Clojure.var("clojure.core", "comp");

        require.invoke(Clojure.read("yang.lang"));
        var fmk = Clojure.var("yang.lang", "fmk");

require ==> #'clojure.core/require
kw ==> #'clojure.core/keyword
comp ==> #'clojure.core/comp
fmk ==> #'yang.lang/fmk

jshell> var m = Map.of("answerToLife", 42, "meaningOfLifeQuestion", "what is the...")
m ==> {answerToLife=42, meaningOfLifeQuestion=what is the...}

jshell> Function<String, String> jdash = x -> CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, x);
jdash ==> $Lambda$34/0x0000000800e60040@213c3543

convert java.util.function.Function / Consumer / BiFunction / BiConsumer to a Clojure function so it later be composed together with other Clojure functions:

jshell> var dashKeys = Yang.toFun(jdash);
dashKeys ==> yang.java$jfun__GT_fun$fn__158@9d7ccfe

compose it:

jshell> fmk.invoke(m, comp.invoke(kw, dashKeys))
$14 ==> {:answer-to-life 42, :meaning-of-life-question "what is the..."}

from Clojure

=> (require '[yang.java :as j])

=> (def m (java.util.HashMap. {"crux.id/foo" {"crux.db/bar" "baz"} "crux.answer/life" 42}))

=> (j/map->edn m)
{:crux.id/foo #:crux.db{:bar "baz"}, :crux.answer/life 42}

license

Copyright © 2020 tolitius

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

yang's People

Contributors

danielmiladinov avatar tolitius avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.