Welcome, I'm happy to see you here! Feel free to pick a function and add a happy example, the more the merrier!
(map cfunction? [ even? (fn []) |($ ) file/read -> ])
# => @[ false false false true false ]
(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 ))(bxor 3 6 ) # => 5
# 011 (3)
# xor 110 (6)
# -------
# 101 (5)
(get (os/environ ) "HOME" ) # => "/Users/cell"
(os/getenv "HOME" ) # => "/Users/cell"
(defn bench `Feed bench a wrapped func and int, receive int for time in ns`
[thunk times ]
(def start (os/clock :cputime :tuple ))
(loop [_ :range [times ]]
(thunk ))
(def end (os/clock :cputime :tuple ))
(/ (+ (* (- (end 0 ) (start 0 )) 1e9 )
(- (end 1 ) (start 1 )))
times ))
# it turns out os/clock is pretty darn fast (comparatively)
(def iterations 2000000 )
(bench |(os/clock :cputime :tuple ) iterations ) # 1283.30053 ns
(bench |(slurp "/proc/self/schedstat" ) iterations ) # 7881.451760 ns
# these basically benchmark slurp
(bench |(do (def f (file/open "/proc/self/schedstat" :r ))
(def content (file/read f :all ))
(file/close f ))
iterations ) # 4894.832760 ns
# even without opening and closing the file, reading in Janet's slower than os/clock
(def f (file/open "/proc/self/schedstat" :r ))
(bench |(do (file/seek f :set 0 )
(def content (file/read f :all ))) iterations ) # 1802.511470 ns
(file/close f )
# Of course bench has some overhead, but it's amortized across iterations anyway
(bench (fn []) 10000000 ) # 42.030338 ns (last [1 1 2 3 5 8 ])
# => 8
(mapcat
|[$0 $1 (* $0 $1 )]
[1 2 3 ]
[100 200 300 ])
# => @[1 100 100 2 200 400 3 300 900] (get default-peg-grammar :h )
# => '(range "09" "af" "AF") (let [len 8
rand-string (string/join (map |(string/format "%02x" $ )
(os/cryptorand len )))]
(= (length rand-string ) (* 2 len )))
# => true
(interleave [:a :b :c ] [1 2 3 ])
# => @[:a 1 :b 2 :c 3]
(interleave [:a :b :c ] (range 3 ))
# => @[:a 0 :b 1 :c 2]
(interleave [:a :b :c ] (range 2 ))
# => @[:a 0 :b 1]
(struct ;(interleave [:a :b :c ] [1 2 3 ]))
# {:c 3 :a 1 :b 2}
(table ;(interleave [:a :b :c ] [1 2 3 ]))
# @{:c 3 :a 1 :b 2} (ev/spawn (os/sleep 1 ) (print "Hard work is done!" ))
# prints "Hard work is done!" after one second
# this is the easiest way to put some forms on the event loop
# but do not forget REPL is blocking, for now, so run the example with `janet -e` (invert "yo" )
# => @{111 1 121 0} (def f (fiber/new (fn [] (yield 2 ) 3 )))
(pp (resume f )) # => 2
(resume f )
(pp (fiber/last-value f )) # => 3
(get-in [[4 5 ] [6 7 ]] [0 ] 42 ) # => (4 5)
(get-in [[4 5 ] [6 7 ]] [0 1 ] 42 ) # => 5
(get-in [[4 5 ] [6 7 ]] [-1 ] 42 ) # => 42
(get-in [[4 5 ] [6 7 ]] [9 9 9 ] 42 ) # => 42
# 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 ))