JanetDocsPlaygroundI'm feeling luckyGitHub sign in

JanetDocs is a community documentation site for the Janet programming language

Loading...

Recent examples

#1) start janet normally, work in the repl, encounter something to debug:

(debug)
# debug: 
#   in thunk [repl] (tail call) on line 4, column 1
# nil
# repl:5:> 

#2) because the -d flag was missing on start, debug is skipping back out into the repl. now i really DO want to debug here and now, without restarting the vm:

(dyn *debug*)
# => nil

#3) we can just set the flag ourself and thus activate the debugger:
(setdyn *debug* :anything_truthy)


(debug)

# debug: 
#   in thunk [repl] (tail call) on line 2, column 1
# entering debug[1] - (quit) to exit
# debug[1]:1:>
*debug*kamisoriPlayground
(defn knorkulate [a b]
  (tracev (+ a (* b b ))))
# <function knorkulate>

(knorkulate 2 34)
# trace on line 2, column 1: (+ a (* b b)) is 1158
# 1158
tracevkamisoriPlayground
(trace +)
# <function +>

((trace +) 5 3)
# trace (+ 5 3)
# 8

(defn knorkulate [a b]
  ((trace +) a ((trace *) b b )))
# <function knorkulate>

(knorkulate 2 34)
# trace (* 34 34)
# trace (+ 2 1156)
# 1158
tracekamisoriPlayground
# Flatten single level of nested collections

(def foo [ [[1 2] [3 4]]   
           [[5 6] [7 8]] ])

(apply array/concat @[] foo) # => @[(1 2) (3 4) (5 6) (7 8)]
array/concatmaradPlayground
trampoline should work at some callback method which will match these code. most provide callback should be like these! 
```c
// liba.so
void call_mul_at_callback(int i, void (*on_complete) (void*,void*), void* user_data) {
  // user_data = ctx
  // work_code
  int v = i * i + i* i * i << 12 - 5 *i;
  printf("from janet ffi\n");
  on_complete(&i, user_data);
  printf("FFI CALLBACK COMPLETE\n");
}
```

```janet
(ffi/context "liba.so")
(ffi/defbind call-mul-at-callback :void (i :int callback :ptr data :ptr))
(def cb (delay (ffi/trampoline :default)))
(call-mul-at-callback 15
                      (cb)
                      (fn[ptr]
                         (let [args (ffi/read (ffi/struct :int) ptr)]
                           (print (string/format "got value %d from ffi"
                                                 (first args))))))
```
ffi/trampolinedG94CgPlayground
(var enabled false)
(toggle enabled)
(print enabled)
# => true
toggleFuriouZzPlayground
# nested iteration
(loop [a :in [100 200 300]
       b :in [1 2 3]]
   (print (+ a b)))

# 101
# 102
# 103
# 201
# 202
# 203
# 301
# 302
# 303
looperichaneyPlayground
(var x 1)
(+= x 2 3 4)
# x = 10
+=erichaneyPlayground
# convert a string to an integer
(peg/match '(number :d+) "123")
#=> @[123]

(first (peg/match '(number :d+) "123"))
#=> 123
peg/matcherichaneyPlayground
(defmacro timeit [& body]
    # generate unique symbols to use in the macro so they can't conflict with anything used in `body`
    (with-syms [$t0 $t1]
        ~(do
            (def $t0 (os/clock :monotonic :double))
            (do ,;body)
            (def $t1 (os/clock :monotonic :double))
            (- $t1 $t0))))

(def time-taken (timeit (os/sleep 0.5)))
(printf "Took %.3f seconds" time-taken)
with-symsAndriamanitraPlayground
(first [])  # => nil
(first "abc")  # => 97
firstAndriamanitraPlayground
(def arr (array :a [:b :c] :d))
# => @[:a (:b :c) :d]
(0 arr)
# => :a
(1 arr)
# => (:b :c)

# out-of-bounds access causes an error
(try
  (3 arr)
  ([err] err))
# => "expected integer key for array in range [0, 3), got 3"

# you may use `get` to avoid the error
(get arr 3)
# => nil
arrayAndriamanitraPlayground
(= math/-inf (- math/-inf 1))
# =>
true
math/-infsogaiuPlayground
# wrap short-fn / | 
(-> 10
    (|(/ $ 2)))
# =>
5

# also wrap fn
(-> 10
    ((fn [n] (/ n 2))))
# =>
5
->sogaiuPlayground
# wrap short-fn / | 
(->> 10
     (|(/ $ 2)))
# =>
5

# also wrap fn
(->> 10
     ((fn [n] (/ n 2))))
# =>
5
->>sogaiuPlayground
(math/acos 0.3)
1.2661036727795
math/acosbtbytesPlayground
 new Math.seedrandom('hello.');
math/seedrandomMonif2009Playground
Math. Seedrandom(3206)
math/seedrandomMonif2009Playground
# Contrived example returning the variadic arguments passed in.
(defmacro example-macro [& args] ~(tuple ,;args))

(example-macro 1 2 3) # => (1 2 3)
(def args [1 2 3])

# `apply` is for functions, but there's always `eval`.
(assert (= (example-macro 1 2 3)
           (eval ~(example-macro ,;args))))
eval4kbytePlayground
# Contrived examples returning the variadic arguments passed in.
(defn example-function [& args] args)
(defmacro example-macro [& args] ~(tuple ,;args))

(macex '(example-macro 1 2 3))

(assert (= (example-function 1 2 3)
           (example-macro 1 2 3)))

(def args [1 2 3])

# `apply` is for functions, but there's always `eval`.
(assert (= (apply example-function args)
           (eval ~(example-macro ,;args))))

# Same return for both.
# => (1 2 3)
apply4kbytePlayground
(defmacro inner [x] ~(do [,x (* ,x ,x)]))
(defmacro outer [n] (map |~(inner ,$0) (range n)))

# Hints:
#
# * Quote the argument.
# * Because it's quoted, the argument can have undefined symbols.
# * Compare the result of `macex` with `macex1`.
# * If needed, print the result with `pp`.
#
(macex '(outer 10))
macex4kbytePlayground
# `parse` can decode arbitrary JDN (Janet Data Notation) encoded by `string/format`

(def encoded (string/format "%j" @{:a 123 :b "foo" :c @{1 [1.2 2.3 3.4]}}))
# => "@{:a 123 :b \"foo\" :c @{1 @[1.2 2.2999999999999998 3.3999999999999999]}}"

(parse encoded)
# => @{:a 123 :b "foo" :c @{1 @[1.2 2.3 3.4]}}
parseCFiggersPlayground
(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