Welcome, I'm happy to see you here! Feel free to pick a function and add a happy example, the more the merrier!
# 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)] (math/hypot 5 12 )
# => 13 (if-let [x true
y (not x )]
:a
:b )
# => :b
(loop [i :range [0 12 ]]
(print i ))
# => 0
# => 1
# => 2
# => 3
# => 4
# => 5
# => 6
# => 7
# => 8
# => 9
# => 10
# => 11
# => nil
(eachp [k v ] {:a "a val" :b "b val" :c "c val" } (print k " - " v ))
# prints c - c val
# prints a - a val
# prints b - b val (buffer/format @"0 - 1 = " "%d" -1 )
# =>
@"0 - 1 = -1" (let [a 1 b 2 c 3 ] (+ a b c )) # => 6
(let
[a 1
b (+ a 1 )
c (+ b 1 )]
(+ a b c )) # => 6
(reduce string "ha" ["ha" "ha" "ha" "ha" ]) # => "hahahahaha"
(accumulate string "ha" ["ha" "ha" "ha" "ha" ]) # => @["haha" "hahaha" "hahahaha" "hahahahaha"] (def f (ev/spawn 4 ))
(ev/sleep 0.0001 ) # give ev a chance in the REPL, remove in file
(fiber/last-value f ) # => 4
(pairs {:a 1 :b 2 :c 3 })
# =>
@[(:c 3 ) (:a 1 ) (:b 2 )]# 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.
# excess elements of the longer list are discarded
(interleave [1 ]
[2 4 ]
[3 6 ])
# -> @[1 2 3] (map dictionary? [ 'ab :ab "ab" @"ab" [97 98 ] @[97 98 ] {0 97 1 98 } @{0 97 1 98 } ])
# => @[ false false false false false false true true ]
(map struct? [ 'ab :ab "ab" @"ab" [97 98 ] @[97 98 ] {0 97 1 98 } @{0 97 1 98 } ])
# => @[ false false false false false false true false ]
(map table? [ 'ab :ab "ab" @"ab" [97 98 ] @[97 98 ] {0 97 1 98 } @{0 97 1 98 } ])
# => @[ false false false false false false false true ] # 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. (string/check-set "0123456789abcdef" "deadbeef" ) # => true