Welcome, I'm happy to see you here! Feel free to pick a function and add a happy example, the more the merrier!
(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 (cmp 1.0 2 )
# => -1
(get default-peg-grammar :a )
# => '(range "az" "AZ") (map function? [ even? (fn []) |($ ) file/read -> ])
# => @[ true true true false true ]
(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 (table ;(kvs (struct :a 1 :b 2 )))
# => @{:a 1 :b 2} (os/sleep 1 ) # => nil
(os/sleep 0.1 ) # => nil
(os/sleep 0 ) # => nil
(find |(string/has-prefix? "a" $ ) ["be" "cat" "art" "apple" ])
# => "art"
(interpose 0 [1 2 3 ])
# -> @[1 0 2 0 3] (def f (ev/spawn 4 ))
(ev/sleep 0.0001 ) # give ev a chance in the REPL, remove in file
(fiber/last-value f ) # => 4
(let [a 1 ]
(let [b a ]
b )) # => 1
# 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. (try
(int/u64 "18446744073709551616" )
([e ] e ))
# => "bad u64 initializer: string" (>= 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 # demo of (@ <sym>) feature
(let [content "# => label" ]
(match [:comment @{} "# => label" ]
[:comment _ (@ content )]
:found
nil ))
# => :found