JanetDocsPlaygroundI'm feeling luckyGitHub sign in

JanetDocs is a community documentation site for the Janet programming language

Loading...

Recent examples

(ffi/context "/usr/lib64/libSDL2.so")

(ffi/defbind SDL_CreateWindow :ptr
    [title :string
     x :int
     y :int
     w :int
     h :int
     flags :uint32])

(ffi/defbind SDL_Delay :void [ms :uint32])
(ffi/defbind SDL_DestroyWindow :void [window :ptr])
(ffi/defbind SDL_Quit :void [])
(def SDL_WINDOW_SHOWN 0x00000004)

(defn main [&]
  (def window (SDL_CreateWindow "Hello world!" 0 0 640 480 SDL_WINDOW_SHOWN))
  (SDL_Delay 4000)
  (SDL_DestroyWindow window)
  (SDL_Quit))
ffi/defbindAndriamanitraPlayground
(print "You are using janet version " janet/version)
janet/versionacadiansithPlayground
(def [pipe-r pipe-w] (os/pipe))

(ev/spawn
  # write to the pipe in a separate fiber
  (for i 0 32000
    (def str (string "Hello Janet " i "\n"))
    (:write pipe-w str))
  (:close pipe-w))

(forever
  (def text (:read pipe-r 4096))
  (when (nil? text) (break))
  (pp text))

# read a series of strings from the pipe in parallel
# to writing to the other side, to avoid the program
# from hanging if the pipe is "full"
#
# see https://github.com/janet-lang/janet/issues/1265
os/pipeYohananDiamondPlayground
(def [stdin-r stdin-w] (os/pipe))
(def [stdout-r stdout-w] (os/pipe))

# write the input that will be sent to sed
(:write stdin-w "hello world 1\nhello world 2")
(:close stdin-w)

(os/execute
  @("sed" "s|world|janet|g")
  :px
  # the program reads from :in and writes to :out
  {:in stdin-r :out stdout-w})

(:read stdout-r math/int32-max)
# => @"hello janet 1\nhello janet 2"

# feed two lines to sed, which replaces "world"
# with "janet", and read the modified results back
os/executeYohananDiamondPlayground
(def [pipe-r pipe-w] (os/pipe))
(:write pipe-w "hello")
(:read pipe-r 5)
# => @"hello"

# send the string "hello" into the writable stream
# part and read it back from the readable one
os/pipeYohananDiamondPlayground
(->> (range 10) (map (fn [arg] (* arg arg))))

# => @[0 1 4 9 16 25 36 49 64 81]
mapGeo-7Playground
(map (fn [arg] (* arg arg)) (range 10))

# => @[0 1 4 9 16 25 36 49 64 81]
mapGeo-7Playground
(def conn-chan (ev/thread-chan 1000))

(defn producer [no]
  (forever
    (ev/sleep 5)
    (print "Adding data from producer num:" no)
    (ev/give conn-chan (math/random))))

(defn consumer [no]
  (forever
    (ev/sleep 0.5)
    (def num (ev/take conn-chan))
    (print num ": Printing from consumer:" no)))

(defn main [& args]
  (ev/spawn-thread (producer 1))
  (ev/spawn-thread (consumer 1))
  (ev/spawn-thread (consumer 2))
  (ev/sleep 20)
  (print "exiting"))
ev/thread-chanGeo-7Playground
# will recursively flatten all indexed-like values
(flatten [1 @[2 [3]] [@[4] 5]])
# => @[1 2 3 4 5]

# only applies to indexed values, other values are untouched
(flatten ["a" :b [:c :d] :e "f"])

# be careful: dictionaries are considered indexed since they define next
(flatten {:a :b})

# however, this only applies to the top value, otherwise it remains untouched
(flatten [{:a :b} {:c :d}])

# if you want only "one cycle of flatten", you want reduce
(reduce array/concat @[] (pairs {:a [:b :c] :d [:e [:f]]}))
# => @[:d (:e (:f)) :a (:b :c)]
flattenCosmicToastPlayground
# use (dyn :args) to get the value of dynamic binding *args*
(let [args (dyn :args)]
  (if (= "-h" (get args 1))
    (print "Usage: janet args.janet [-h] ARGS..")
    (printf "command line arguments:\n %q" args)))
*args*AndriamanitraPlayground
# Run this in a file.
# Notice how each thread gets its own copy of the environment,
# including the global 'counter' variable.

(var counter 0)
(defn start-thread [name sleep]
  (def chan (ev/thread-chan))
  (ev/spawn-thread
    (repeat 10
      (ev/sleep sleep)
      (++ counter)
      (print name " counter is " counter))
    (print name " has finished")
    (ev/give chan "done"))
  chan)

# Spawn two threads that increment counter
(def chan-a (start-thread "Slow thread" 0.8))
(def chan-b (start-thread "Fast thread" 0.45))

# Wait for both threads to finish
(ev/take chan-a)
(ev/take chan-b)
(print "Global counter is still " counter)
ev/spawn-threadfuxoftPlayground
(tabseq [i :in (range 97 100)]
  i (string/from-bytes i))
# =>
@{97 "a"
  98 "b"
  99 "c"}
tabseqsogaiuPlayground
(var abc 123)
(= 356 (with-vars [abc 456] (- abc 100)))
with-varsnunziocPlayground
(def channel (ev/chan))

(ev/spawn
 (do
   (for i 0 10
     (ev/give channel (math/random))
     (ev/sleep 0.25))
   (ev/chan-close channel)))

(defn consumer [name delay]
  (loop [item :iterate (ev/take channel)]
    (match item
      [:close _] nil
      v (print name " got " v))))

(ev/call consumer "bob" 1)
(ev/call consumer "alice" 3)
ev/chan-closetxgruppiPlayground
(map tuple ["a" "b" "c" "d"] [1 2 3 4] "abcd")

# => @[("a" 1 97) ("b" 2 98) ("c" 3 99) ("d" 4 100)]
mapfelixrPlayground
# absolute value of negatives, ignore positives
(keep |(if (< $ 0) (- $) nil) [-1 2 -3 -4 -5 6]) # -> @[1 3 4 5]

# halves each even number, ignores odds
(keep |(when (even? $) (/ $ 2)) [1 2 8 7 -2])    # -> @[1 4 -1]
keepTechcablePlayground
(defn get-time-str []
  (let [{:hours h :minutes m :seconds s} (os/date)]
    (string h ":" m ":" s)))

(get-time-str) => "23:18:16"
os/datetupini07Playground
(->> "X"
     (string "a" "b")
     (string "c" "d")
     (string "e" "f"))  # => "efcdabX"
->>uvtcPlayground
(-> "X"
    (string "a" "b")
    (string "c" "d")
    (string "e" "f"))  # => "Xabcdef"
->uvtcPlayground
(defn eval-string
  ``Evaluates a string in the current environment. If more control over the
  environment is needed, use `run-context`.``
  [str]
  (var state (string str))
  (defn chunks [buf _]
    (def ret state)
    (set state nil)
    (when ret
      (buffer/push-string buf str)
      (buffer/push-string buf "\n")))
  (var returnval nil)
  (run-context {:chunks chunks
                :on-compile-error (fn compile-error [msg errf &]
                                    (error (string "compile error: " msg)))
                :on-parse-error (fn parse-error [p x]
                                  (error (string "parse error: " (:error p))))
                :fiber-flags :i
                :on-status (fn on-status [f val]
                             (if-not (= (fiber/status f) :dead)
                               (error val))
                             (set returnval val))
                :source :eval-string})
  returnval)
run-contexttionisPlayground
(find-index |(= $ "b") ["a" "b" "c" "d"]) #=> 1
find-indexAlecTroemelPlayground
(defn f1 [s] (string "-" s "-"))
(defn f2 [s] (string "=" s "="))
(defn f3 [s] (string "#" s "#"))

(def f (juxt f1 f2 f3))

(f "x") # => ("-x-" "=x=" "#x#")
juxtuvtcPlayground
(pairs {:a 1 :b 2 :c 3})
# =>
@[(:c 3) (:a 1) (:b 2)]
pairsuvtcPlayground
(group-by odd? [1 2 3 5 6])
# =>
@{false @[2 6] true @[1 3 5]}
group-byuvtcPlayground
(def ds @[@{:a 1 :b 2}
          @{:a 8 :b 9}])

(defn thrice [x] (* x 3))

(update-in ds [0 :b] thrice)

# `ds` is now
@[@{:a 1 :b 6}
  @{:a 8 :b 9}]
update-inuvtcPlayground
(print math/int-min)
-9007199254740992
nil
math/int-minbtbytesPlayground
(file/open "iamfile.txt" :r)
(file/open "iamfile.txt" :w)
(file/open "iamfile.txt" :a)
file/openjgartePlayground
(seq [i :range [0 3]
      j :range [0 3]
      :let [c (string/format "%c" (+ 97 i))]
      :when (and (even? i) (even? j))]
  [(keyword c) j])
# => '@[(:a 0) (:a 2) (:c 0) (:c 2)]
seqsogaiuPlayground
(seq [i :range [0 3]
      j :range [0 3]
      :let [c (string/format "%c" (+ 97 i))]]
  [(keyword c) j])
# => '@[(:a 0) (:a 1) (:a 2) (:b 0) (:b 1) (:b 2) (:c 0) (:c 1) (:c 2)]
seqsogaiuPlayground
(seq [i :range [0 3]
      j :range [0 3]]
  [(keyword (string/format "%c" (+ 97 i)))
   j])
# => '@[(:a 0) (:a 1) (:a 2) (:b 0) (:b 1) (:b 2) (:c 0) (:c 1) (:c 2)]
seqsogaiuPlayground