triallax changed the topic of #numbat to: The Official Numbat channel https://numbat.dev | This channel is publicly logged at https://libera.irclog.whitequark.org/numbat | Please read https://workaround.org/getting-help-on-irc/ if you're new to IRC!
potash has quit [Quit: The Lounge - https://thelounge.chat]
potash has joined #numbat
Charbot9000 has joined #numbat
<achin> i've added very basic numbat suppport to an existing irc bot i've been building
<achin> !nb 1 cm ^3 -> teaspoon
<Charbot9000> 1 × centimetre³ ➞ teaspoon = 0.202884 teaspoon [Volume]
<achin> it's built with the latest git commit, so you can do stuff like:
<achin> !nb element("W").melting_point // celsius
<Charbot9000> celsius(element("W").melting_point) = 3406.85
Charbot9000 has quit [Read error: Connection reset by peer]
Charbot9000 has joined #numbat
Charbot9000 has quit [Remote host closed the connection]
Charbot9000 has joined #numbat
sharkdp has joined #numbat
<sharkdp> achin: Awesome! Now we just need to add an `exec(…)` function and we can do fun stuff on your machine :-)
<sharkdp> !nb now() -> tz("Europe/Berlin")
<Charbot9000> tz("Europe/Berlin")(now()) = Fri, 17 May 2024 09:00:36 +0200 [DateTime]
sharkdp has quit [Remote host closed the connection]
sharkdp has joined #numbat
<triallax> achin: aww you beat me to it
<triallax> sharkdp: if i were to do it i would wrap the numbat call in bwrap or something just to be safe
<triallax> !nb sin(90 deg)
<Charbot9000> sin(90 degree) = 1
<triallax> very neat
<triallax> what if i do this
<triallax> !nb print("foo")
<Charbot9000> print("foo")
<triallax> hmm
<sharkdp> Output is generated in a different way then the result of expressions. The Numbat API is a bit convoluted w.r.t. this at the moment
<triallax> yeah i'm aware of that
<triallax> i wonder if the bot has a single numbat instance or it juts runs it for each expression
<triallax> !nb let x = 1
<Charbot9000> let x: Scalar = 1
<triallax> !nb x
<Charbot9000> x = 1
<triallax> nice
<triallax> but definitely has to be sandboxed with bwrap or something
<sharkdp> Is that a good idea? hmm
<triallax> i think so
<triallax> why wouldn't it be?
<sharkdp> I mean the global state
<sharkdp> not the sandboxing
<triallax> i think so
<triallax> so we can add e.g. functions
<sharkdp> what about currency conversions?
<sharkdp> !nb 10 € -> USD
<Charbot9000> Error: Unknown identifier 'USD'.
<triallax> having a command to restart it would be nice
<triallax> huh, why doesn't that work
<triallax> !nb quit
<Charbot9000> Error: Unknown identifier 'quit'.
<triallax> how does it do this
<triallax> is it hooking up to the numbat api?
<sharkdp> the currency module needs to be loaded explicitly, that's why it doesn't work, I guess
<sharkdp> and commands like "quit" are not part of the language. They are just used inside the CLI and the Web App
<triallax> yeah
<triallax> i thought the bot was shelling out to the numbat command but it seems not
potash has quit [Quit: Ping timeout (120 seconds)]
potash has joined #numbat
<achin> i didn't yet enable currency fetching, just because it was late and i was tired and i wanted to get something working
<achin> and yes, this uses the numbat API, not a numbat subprocess
<sharkdp> Very cool. What would happen if I send:
<sharkdp> fn forever<A>(x: A) = f(x)
<sharkdp> forever(0)
<triallax> what does numbat itself do in that case
<triallax> stack overflow?
<triallax> uhh it doesn't work
<sharkdp> it needs to be `fn forever<A>(x: A) -> A = f(x)`
<triallax> seems like you can't recurse in numbat
<triallax> sharkdp: but what's f in this case
<sharkdp> ah, sorry. `forever` of course
<sharkdp> fn forever<A>(x: A) -> A = forever(x)
<triallax> ah it works if i add the return type
<sharkdp> yes, that's what I wanted to say
<triallax> that is very weird
<triallax> i get an unknown identifier error
<triallax> so i guess it's because numbat is trying to infer the return type of the function?
<triallax> and when it does infer it it adds the function name to the scope?
<achin> sharkdp: it would hang the bot, probably :)
<triallax> so if the return type is explicitly stated then it can just add it to the scope directly
<triallax> right
<triallax> if the limitation isn't going away anytime soon would be nice if we had a better error message
<sharkdp> true
<achin> i'm not sure how to prevent this. i doubt numbat could reliably prevent infinitly recursive calls. but i really cared about this in the bot, i would probably run numbat in wasmtime configured with fuel https://docs.rs/wasmtime/latest/wasmtime/struct.Config.html#method.consume_fuel
<triallax> that's impossible isn't it
<triallax> actually is numbat turing complete
<triallax> in its current form
<triallax> i guess since it supports recursion yes?
<sharkdp> consume_fuel, I like it
<sharkdp> I would be surprised if it weren't turing complete :-). Recursion is not enough, you also need a "tape". But since we have strings...
<sharkdp> Or probably you can also use the binary representation in numbers as your (not so infinite) tape
<triallax> i only have a general understanding of turing completeness unfortunately, i haven't been taught anything about it yet
<triallax> actually it's pretty crazy that the whole first year of comp scpi never touched on this
<triallax> but yeah of course we'd need a tape
<achin> i'm sure you could use that fib example (which is guarenteed to complete in finite time), but give it a sufficiently large input so that it will take "too long" for your given use case
<achin> i dunno if it would be expensive to count how often we recurse and put a [configurable] limit on that
<sharkdp> For the IRC bot, that would be useful. But otherwise.. why should we?
<achin> not sure
<achin> having a "RunTooLong" runtime error might be a better user experience than having to ctrl-c a CLI numbat process (thus losing your context)
<achin> but maybe no one actually runs into this problem in the real world
<triallax> or otherwise it could also be nice to terminate the evaluation of an expression
<triallax> but that might be a bit tricky to do
<sharkdp> as for "what happens if you call forever(0) in the CLI": it will not cause a (Rust) stack overflow. Insect would have done that. But the bytecode VM is not a recursive interpreter. What happens instead is that we grow the (Numbat) stack indefinitely ... because we don't have tail call optimization. So it eventually will be killed by the OS when it runs OOM.
<sharkdp> I mean.. something like Python does ("maximum recursion depth exceeded") might make sense, yes.
<achin> !nb fn fib(n: Scalar) -> Scalar = if n <= 2 then 1 else fib(n - 2) + fib(n - 1)
<Charbot9000> fn fib(n: Scalar) -> Scalar = if (n ≤ 2) then 1 else (fib(n - 2) + fib(n - 1))
<achin> !nb fib(20)
<Charbot9000> fib(20) = 6765
<achin> !nb fib(30)
<triallax> rip bot
<Charbot9000> fib(30) = 832_040
<achin> !nb fib(32)
<Charbot9000> fib(32) = 2_178_309
<achin> since numbat is fully synchronous, all this runs synchronously in an otherwise async bot, so tokio is probably not very happy about this
<achin> but oh well
<achin> the above topics are fun to think about, but in practice i don't actually care if the numbat runs the bot out of memory
<triallax> i'd be more concerned about the bot hanging for however long it takes to oom
<sharkdp> It probably only shows abbreviated error messages?
<sharkdp> !nb 1 month + 1 lightyear
<Charbot9000> Error: left hand side: Time
<triallax> !nb list
<Charbot9000> Error: Unknown identifier 'list'.
<triallax> yeah of course
<sharkdp> !nb get_local_timezone()
<Charbot9000> get_local_timezone() = US/Eastern [String]
<achin> at the moment, error handling is very basic, it just takes the Display representation of the error returned by interpret_with_settings()
<achin> i'm also not yet 100% sold on having the bot echo the input statements before the result, but at the moment i think i like it
<sharkdp> I added a detailed description to https://github.com/sharkdp/numbat/pull/432. Maybe we can find a useful intermediate state that we can merge before tackling the deeper type-theoretic issues.
<sharkdp> I guess we would need to implement most functions via the FFI for now.
sharkdp has quit [Remote host closed the connection]
Charbot9000 has quit [Remote host closed the connection]
Charbot9000 has joined #numbat
<achin> sharkdp: i updated the bot to use your latest lists PR
<achin> !nb head([1 foot, 2 inches])
<Charbot9000> head([1 foot, 2 inch]) = 1 ft [Length]
<achin> !nb fn sum<T>(list: List<T>) -> T = if len(list) == 1 then head(list) else head(list) + sum(tail(list))
<Charbot9000> fn sum<T>(list: List<T>) -> T = if (len(list) == 1) then head(list) else (head(list) + sum(tail(list)))
<achin> !nb sum([1 foot, 2 inches, 3 millimeters])
<Charbot9000> sum([1 foot, 2 inch, 3 millimetre]) = 1.17651 ft [Length]
Charbot9000 has quit [Remote host closed the connection]
Charbot9000 has joined #numbat
potash has quit [Read error: Connection reset by peer]
potash has joined #numbat