Welcome, I'm happy to see you here! Feel free to add a happy example, the more the merrier!
# By default, top level defs can be optimized better:
(defn let-sum [] (let [a 1 b 2 c 3 ] (+ a b c )))
(def a 1 )
(def b 2 )
(def c 3 )
(defn top-def-sum [] (+ a b c ))
(disasm let-sum ) # (ldi 0 1) (ldi 1 2) (ldi 2 3) (add 3 0 1) (add 3 3 2)
(disasm top-def-sum ) # (ldi 0 1) (addim 1 0 2) (addim 1 1 3)
# But with *optimize* level 3, they are both better
# n.b. func must be (re)defined after *optimize* is set
(setdyn *optimize* 3 )
(defn let-sum [] (let [a 1 b 2 c 3 ] (+ a b c )))
(defn top-def-sum [] (+ a b c ))
(disasm let-sum ) # (ldi 0 6)
(disasm top-def-sum ) # (ldi 0 6)
# currently, implemented optimizations are mostly in 1 and 2 # Janet numbers are "doubles" representing each int up to 2^53 (9007199254740992)
# Above this, they can't, so these both eval to the same thing!
(math/exp2 53 )
(+ 1 (math/exp2 53 ))
# After 2^53, doubles only represent even numbers
# Janet prints numbers above 2^53 in exponent form, hiding the end
(+ 2 (math/exp2 53 )) # 9.00719925474099e+15
# But the odd numbers round interestingly!
# 2^53 + 2, 2^53 + 4 etc. are slots. We choose which to round e.g. 2^53 + 3 into.
# In school, we round .5 up, doubles above 2^53 round .5 to the neighbor divisible by 4!
(def p53 (math/exp2 53 ))
(= (+ p53 1 ) p53 ) # true
(= (+ p53 2 ) p53 ) # false
(= (+ p53 1 ) (+ p53 2 )) # false
(= (+ p53 3 ) (+ p53 2 )) # false
(= (+ p53 3 ) (+ p53 4 )) # true
(= (+ p53 5 ) (+ p53 4 )) # true
(= (+ p53 5 ) (+ p53 6 )) # false
(= (+ p53 7 ) (+ p53 8 )) # true
(= (+ p53 9 ) (+ p53 8 )) # true
# After 2^54, it's the neighbor divisible by 8.
# After 2^55, it's the neighbor divisible by 16!
# It continues this way until 2^1024, which overflows to infinity
(= math/inf (math/exp2 1024 )) # true # If you have a working project.janet file, you can use it from janet-pm with just this:
(import spork/declare-cc )
(dofile "project.janet" :env (declare-cc/jpm-shim-env ))(let (sinlu (array/new 10 )) # 10 element look up table.
(for i 0 10 (put sinlu i (math/sin (* math/pi (/ i 10 )))))
(pp sinlu ))(let (x @["This" "is" "a" ] # Must be array.
y @["test" "of" ]
z ["the" "emergency!" ]) # Tuple OK for part.
(pp (array/join x y z )))
# @["This" "is" "a" "test" "of" "the" "emergency!"] (import spork/json )
(def input `` {"name": "person", "unknown": null, "happy": true, "sad": false} `` )
When calling , the json dictionary becomes a mutable table in janet.
(json/decode input )
@{"happy" true "name" "person" "sad" false "unknown" :null }
pass `true` as the first arg , and json keys become janet keywords.
(json/decode input true )
@{:happy true :name "person" :sad false :unknown :null }
pass `true` as the second arg , and json keys that map to `null` are not hydrated.
(json/decode input true true )
@{:happy true :name "person" :sad false }
(print "The build hash of your Janet executable is " janet/build "." )# Janet v1.42.0 -- See %src/include/janet.h.
(defn set? [position ] (["not set" "set" ] (band janet/config-bits position )))
(printf ```
Configurations:
* NANBOX %s.
* SINGLE_THREADED %s.
* NANBOX_64_POINTER_SHIFT %s.``` (set? 0x1 ) (set? 0x2 ) (set? 0x4 ))
(def cc (ev/thread-chan 99 )) # Sets up a message channel.
(def ww (filewatch/new cc )) # Creates the watcher.
(filewatch/add ww "ftest.janet" :all ) # Watch for all changes.
(filewatch/add ww "fadd.janet" :modify ) # Only care if modified.
(filewatch/listen ww ) # Start filewatcher listening for changes.
# Note that we may still get events for files that have been removed
# so we have to make sure we don't remove them twice.
(var careless "Have we already removed %fadd.janet?" false )
(forever
(let (item (ev/take cc ))
(pp (ev/take cc ))
(when (and (not careless ) (= "fadd.janet" (item :wd-path )))
(print "I don't care about this file anymore." )
(filewatch/remove ww (item :wd-path ))
(set careless true )
)))(def cc (ev/thread-chan 99 )) # Sets up a message channel.
(def ww (filewatch/new cc )) # Creates the watcher.
(filewatch/add ww "ftest.janet" :all ) # Watch for all changes.
(filewatch/add ww "fadd.janet" :modify ) # Only care if modified (Linux-specific flag).
(filewatch/listen ww ) # Start filewatcher listening for changes.
(pp (ev/take cc )) # Print info on first file to change.
(filewatch/unlisten ww ) # Stop caring about changes. (def cc (ev/thread-chan 99 )) # Sets up a message channel.
(def ww (filewatch/new cc )) # Creates the watcher.
(filewatch/add ww "ftest.janet" :all ) # Watch for all changes.
(filewatch/add ww "fadd.janet" :modify ) # Only care if modified.
(filewatch/listen ww ) # Start filewatcher listening for changes.
(pp (ev/take cc )) # Print info on first file to change.
(filewatch/unlisten ww ) # Stop caring about changes.
# This allows the program to exit -- otherwise
# filewatcher listening thread keeps running.
(def cc (ev/thread-chan 99 )) # Sets up a message channel.
(def ww (filewatch/new cc )) # Creates the watcher.
(filewatch/add ww "ftest.janet" :all ) # File to watch.
(filewatch/listen ww ) # Start filewatcher listening for changes.
(ev/spawn-thread # Spawn thread to catch change events.
(print "Waiting..." )
(forever (pp (ev/take cc ))))(def cc (ev/thread-chan 99 )) # Sets up a message channel.
(def ww (filewatch/new cc )) # Creates the watcher.
(filewatch/add ww "ftest.janet" :all ) # File to watch.
(filewatch/listen ww ) # Start filewatcher listening for changes.
(ev/spawn-thread # Spawn thread to catch change events.
(print "Waiting..." )
(forever (pp (ev/take cc ))))(when (def x 10 )
(string "Got value: " x ))
# "Got value: 10"
(when (def x nil )
(string "Got value: " x ))
# nil # Since table/clone produces a shallow copy and composing freeze and thaw makes everything mutable/immutable
(defn deep-clone [ds ]
(prewalk
|(cond
(table? $ ) (table/clone $ )
(array? $ ) (array/slice $ )
(buffer? $ ) (buffer/slice $ )
$ )
ds ))
# CalebF wrote this: https://janet.zulipchat.com/#narrow/channel/409517-help/topic/table.2Fclone.20doesn.27t.20make.20a.20deep.20copy.3F/near/617675442 (import spork/misc )
(def d (misc/capout (doc misc/capout )))
d # returns:
@"\n\n macro\n /usr/local/lib/janet/spork/misc.janet on
line 340, column 1\n\n \e[97m(capout & body)\e[39m\n\n
Captures the standard output of the variadic \e[97mbody\e[39m
and returns it as \n a buffer.\n\n\n"
# Get all matches, similar to a global regular expression
(peg/match '(any (+ (<- :a+ ) 1 )) "Hello, world!" )
# => @["Hello" "world"]
(peg/match '(any (+ (number :d ) 1 )) "1A2B3C4D5" )
# => @[1 2 3 4 5]
(peg/match '(any (+ (<- :a+ ) 1 )) "12345" )
# => @[] (mapcat
|[$0 $1 (* $0 $1 )]
[1 2 3 ]
[100 200 300 ])
# => @[1 100 100 2 200 400 3 300 900] # If your tooling or the compiler doesn't believe a symbol will be bound e.g.:
(def a b ) # if b e.g. gets bound by some macro or pushed directly to the env
# You can wrap it with compwhen on a bool:
(var- bla false )
(compwhen bla
(def a b ))
# Whatever defines b should then set bla to true
# From: https://codeberg.org/veqq/declarative-dsls/src/branch/master/src/declarative-dsls/logic.janet # To make a package conditionally export from another:
# A package can see whether another module was already imported,
# and conditionally act and e.g. import it and rebind/export some symbols:
(var- bla false )
(compwhen (not (some |(string/has-suffix? "dataframes.janet" $ ) (keys module/cache )))
(import declarative-dsls/dataframes :as "no" :export false )
(set bla true ))
(compwhen bla
(def print-as-table no/print-as-table )
(def select no/select )
(def populate-df! no/populate-df! )
(def rows->dataframe no/rows->dataframe )
(def dataframe->rows no/dataframe->rows ))
# From: https://codeberg.org/veqq/declarative-dsls/src/branch/master/src/declarative-dsls/logic.janet