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

# To make "stub functions" in an image, solving c interop problems like this:

# I hoped that I would be able to unmarshal the runtime.jimage, load my C functions,
# and Janet would use my app's functions instead of the stubs. However, during
# compilation, Janet seems to precompile all the top-level function calls. This
# means hotswapping the functions does nothing, and the Janet code continues to 
# use the stubs instead.
#
# I was hoping that there would be some way of telling Janet "don't precompile 
# this please", either a (defstubn ...) or the ability to do 
# (defn internal/redraw-ui [opts] (dyn)), where (dyn) is some abstract type that
# Janet can't precompute directly.
# https://github.com/janet-lang/janet/issues/1642


# pretend this is the stub function we want to replace
(defn greet [] (print "hello world"))

# make-image-dict determines which values will be filled in at
# "deserialization" time
(put make-image-dict greet 'greet)
(def pretend-env @{
  'some-function (fn [] (greet) (greet))})

(def compiled (make-image pretend-env))
# notice: the string "hello world" does not appear in the compiled result
(pp compiled)

# if we just try to (load-image compiled) at this point, it will raise,
# because we haven't specified what to do about 'greet

# we have to make an entry in the load-image-dict. note that
# it does not have to be the same value!
(put load-image-dict 'greet (fn [] (print "something else!")))

# now we can call load-image
(def pretend-env-reparsed (load-image compiled))

# and when we run this, we will see the replacement that we gave
((pretend-env-reparsed 'some-function))
make-image-dictveqqqPlayground
(take-while number? @[1 2 3 "4" 5 6 7 8 9 "10" 11 "12"]) # => (1 2 3)
take-whilejgartePlayground
(peg/replace-all '(set "aiou") "e" "The quick brown fox jumps over the lazy dog")
# returns The qeeck brewn fex jemps ever the lezy deg
peg/replace-allpepePlayground
(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
(peg/find ':d "Battery temperature: 40 °C")
# => 21 index of the first number
peg/findpepePlayground
(def f (generate [i :range [0 5]] (+ i i)))

(print (fiber/status f))
(print (resume f)) 
(print (resume f)) 
(print (resume f)) 
(print (resume f)) 
(print (resume f)) 
(print (fiber/status f)) # -> :pending
(print (resume f)) 
(print (fiber/status f)) # -> :dead


# :new
# 0
# 2
# 4
# 6
# 8
# :pending
#
# :dead
generateleobmPlayground
# *doc-width* is bound to the keyword :doc-width - it can be used in place of
# :doc-width in a call to `dyn`, `setdyn`, or `with-dyns` and is preferable
# to using the keyword directly. When set to a number, it indicates the
# maximum width (in columns) of a row of text returned by `doc-format`.

# - Like *doc-color*, *doc-width* can be used to adjust the output of
#   `doc-format`.
# - When the :doc-width dynamic binding is not set, the default width is 80.
# - By default, `doc-format` adds 4 space indentation and subtracts 8 from
#   the value of the :doc-width dynamic binding to calculate a max width.

# Default:
# repl> (doc doc)
# 
# 
#     macro
#     boot.janet on line 3573, column 1
# 
#     (doc &opt sym)
# 
#     Shows documentation for the given symbol, or can show a list of 
#     available bindings. If sym is a symbol, will look for documentation 
#     for that symbol. If sym is a string or is not provided, will show 
#     all lexical and dynamic bindings in the current environment 
#     containing that string (all bindings will be shown if no string is 
#     given).

# With *doc-width*:
# repl> (with-dyns [*doc-width* 40] (doc doc))
# 
# 
#     macro
#     boot.janet on line 3573, column 1
# 
#     (doc &opt sym)
# 
#     Shows documentation for the 
#     given symbol, or can show a 
#     list of available bindings. 
#     If sym is a symbol, will 
#     look for documentation for 
#     that symbol. If sym is a 
#     string or is not provided, 
#     will show all lexical and 
#     dynamic bindings in the 
#     current environment 
#     containing that string (all 
#     bindings will be shown if 
#     no string is given).
*doc-width*quexxonPlayground
(or true)        # => true
(or true true)   # => true
(or true false)  # => true

(or false 1 2)  # => 1
(or false 2 1)  # => 2

(or false nil)  # => nil
(or nil false)  # => false

# note that `or` does not behave as you might expect
# when used with `apply` and `splice`:
(or 1 2 3)             # => 1
(or (splice [1 2 3]))  # => (1 2 3)
(apply or [1 2 3])     # => (if 1 1 (if 2 2 3))
orcellularmitosisPlayground
(map indexed?    [ 'ab   :ab   "ab"   @"ab"  [97 98]  @[97 98]  {0 97 1 98}  @{0 97 1 98}  ])
# =>            @[ false false false  false  true     true      false        false         ]

(map tuple?      [ 'ab   :ab   "ab"   @"ab"  [97 98]  @[97 98]  {0 97 1 98}  @{0 97 1 98}  ])
# =>            @[ false false false  false  true     false     false        false         ]

(map array?      [ 'ab   :ab   "ab"   @"ab"  [97 98]  @[97 98]  {0 97 1 98}  @{0 97 1 98}  ])
# =>            @[ false false false  false  false    true      false        false         ]
tuple?cellularmitosisPlayground
(def ast '(print novar))
(def es (compile ast))
# => @{:column 11 :line 12 :error "unknown symbol novar"} returns struct with error on invalid ast
compilepepePlayground
# foo.txt is a file with contents "hello\nworld\n".
(slurp "foo.txt")  # => @"hello\nworld\n"
(string/split "\n" (slurp "foo.txt"))  # => @["hello" "world" ""]

(defn slurp-lines [path]
  (string/split "\n" (slurp path)))

(slurp-lines "foo.txt")  # => @["hello" "world" ""]

(string/join @["hello" "world" ""] "\n")  # => "hello\nworld\n"
(spit "foo2.txt" (string/join @["hello" "world" ""] "\n"))
# The contents of foo.txt and foo2.txt are now identical.

(defn spit-lines [path lines]
  (spit path (string/join lines "\n")))

(spit-lines "foo3.txt" (slurp-lines "foo.txt"))
# The contents of foo.txt and foo3.txt are now identical.
slurpcellularmitosisPlayground
(filter  even?                     [1 2 3 4 5])  # => @[2 4]
(filter  odd?                      [1 2 3 4 5])  # => @[1 3 5]
(filter  (fn [x] (not (even? x)))  [1 2 3 4 5])  # => @[1 3 5]
(filter  (complement even?)        [1 2 3 4 5])  # => @[1 3 5]

(def fns [even? odd?])
(map  (fn [f] (filter f [-2 -1 0 1 2]))  fns)  # => @[ @[-2 0 2] @[-1 1]   ]
(def fns (map complement fns))
(map  (fn [f] (filter f [-2 -1 0 1 2]))  fns)  # => @[ @[-1 1]   @[-2 0 2] ]
complementcellularmitosisPlayground
# removes a file in the current directory
(os/rm "hello.txt")
os/rmswlkrPlayground
(spit "/tmp/hello.sh" "#!/bin/bash\necho 'Hello from Bash!'\n")
(os/chmod "/tmp/hello.sh" "rwx------")
(os/setenv "PATH" (string (os/getenv "PATH") ":/tmp"))
(os/shell "hello.sh")
os/setenvcellularmitosisPlayground
(defn array-difference [array-1 array-2]
  (filter |(not (has-value? array-2 $)) array-1))

(array-difference [1 2 3 4 5] [2 3 4]) # => @[1 5]
has-value?veqqqPlayground