JanetDocsSourcePlaygroundTutorialsI'm Feeling luckyCommunityGitHub sign in

Community documentation for Janet

Supported Modules

Welcome, I'm happy to see you here! Feel free to pick a function and add a happy example, the more the merrier!

Loading...

Random Examples

(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
(cmp 1.0 2)
# => -1
cmpsogaiuPlayground
(get default-peg-grammar :a)
# => '(range "az" "AZ")
default-peg-grammarsogaiuPlayground
(map function? [ even?  (fn [])  |($)  file/read  ->   ])
# =>          @[ true   true     true  false      true ]
function?cellularmitosisPlayground
(os/execute
  ["/usr/bin/bash" "-c" "set"]
  :e
  @{"SOME" "value"
    "OTHER" "one"})
# => 0

# execute bash and prints environment variables
# which contains SOME=value and Other=one
os/executegoldenHairDafoPlayground
(table ;(kvs (struct :a 1 :b 2)))
# => @{:a 1 :b 2}
tablesogaiuPlayground
(os/sleep 1)    # => nil
(os/sleep 0.1)  # => nil
(os/sleep 0)    # => nil
os/sleepcellularmitosisPlayground
(find |(string/has-prefix? "a" $) ["be" "cat" "art" "apple"])

# => "art"

findveqqqPlayground
(interpose 0 [1 2 3])
# -> @[1 0 2 0 3]
interposeKrasjetPlayground
(def f (ev/spawn 4))
(ev/sleep 0.0001) # give ev a chance in the REPL, remove in file
(fiber/last-value f) # => 4
fiber/last-valuepepePlayground
(let [a 1]
 (let [b a]
  b)) # => 1
letjgartePlayground
# Consider this problem: As a module author, I want to define a dynamic
# binding `:debug` to provide additional diagnostic information when an
# error occurs in a module function. I'll use `defdyn` to create a public
# alias for my dynamic binding:

# In the file: my-mod.janet
# The `defdyn` macro creates the dynamic binding :debug, and explicitly
# exposes it in the module's API as `my-mod/*debug*`.
(defdyn *debug*)

# contrived function - the important thing is that it enables additional
# diagnostic logging when the `*debug*` alias's reference dynamic binding
# is true.
(defn my-func [& params]
  (try
    (do
      (when (empty? params)
        (error "missing required argument")))
    ([err fib]
      (when (dyn *debug*)
        (print "[diagnostics] ..."))
      (error (string "error occurred: " err)))))

# Let's test our module from the REPL.

# $ repl:1:> (import /my-mod)
# $ repl:2:> (setdyn my-mod/*debug* true) # enable debug mode
# $ repl:3:> (my-mod/my-func)
# [diagnostics] ...
# error: error occured: missing required argument
#   in my-func [my-mod.janet] on line 11, column 7
#   in thunk [repl] (tail call) on line 4, column 1
# entering debug[1] - (quit) to exit
# debug[1]:1:>

# We see our diagnostic message, but we also entered Janet's built-in
# debugger! That's not what we intended. Why did this happen?

# It turns out that our module's `my-mod/*debug*` alias is namespaced, but the
# referenced `:debug` dynamic binding is not. We've created a collision with
# the `:debug` dynamic binding in the core API that activates the debugger
# on error.

# $ repl> *debug*
:debug
# $ repl> my-mod/*debug*
:debug

# The solution is to set the :defdyn-prefix dynamic binding to add a namespace
# for all dynamic bindings in our module. We should use a reasonably unique
# prefix - let's go with the name of the module's public git repo. It's okay
# for the prefix to be long - it will be used as the key for the dynamic
# binding in the current environment, but the user won't typically interact
# with it directly. The prefix is effectively "hidden" from the user. We'll
# prepend this line at the top of our module:
(setdyn *defdyn-prefix* "codeberg.org/quexxon/my-mod/")

# Now our `my-mod/*debug*` alias refers to an isolated, namespaced binding:
# $ repl:1:> (import /my-mod)
# $ repl:2:> my-mod/*debug*
:codeberg.org/quexxon/my-mod/debug
# $ repl:3:> (setdyn my-mod/*debug* true) # enable debug mode
# $ repl:4:> (my-mod/my-func)
# [diagnostics] ...
# error: error occured: missing required argument
#   in my-func [my-mod.janet] on line 11, column 7
#   in thunk [repl] (tail call) on line 4, column 1
# $ repl:5:>

# Much better! We see our diagnostic message, but we didn't trigger Janet's
# debugger. As a general rule, always set `*defdyn-prefix*` to a unique
# value when defining dynamic bindings for your module.
*defdyn-prefix*quexxonPlayground
(try
  (int/u64 "18446744073709551616")
  ([e] e))
# => "bad u64 initializer: string"
int/u64sogaiuPlayground
(>= 4 2)
# => true 

# multiple values
(>= 4 4 3 2 1 1)
# => true 

# with array in apply call
(apply >= [4 4 3 2 1 1])
# => true 

# with array in splice form
(>= ;[4 4 3 2 1 1])
# => true 
>=leobmPlayground
# demo of (@ <sym>) feature
(let [content "# => label"]
  (match [:comment @{} "# => label"]
    [:comment _ (@ content)]
    :found
    nil))
# => :found
matchsogaiuPlayground