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!
sharkdp has joined #numbat
sharkdp has quit [Remote host closed the connection]
sharkdp has joined #numbat
sharkdp has quit [Remote host closed the connection]
sharkdp has joined #numbat
sharkdp has quit [Remote host closed the connection]
sharkdp has joined #numbat
sharkdp has quit [Remote host closed the connection]
sharkdp has joined #numbat
sharkdp has quit [Remote host closed the connection]
sharkdp has joined #numbat
<sharkdp> The type inference & list datatype changes have been merged! The latest version is also online at https://numbat.dev/.
<triallax> fantastic!
<sharkdp> As far as I can tell, there are only very minor regressions (worse error messages in some edge cases and some details in pretty printing).
<sharkdp> And those should be solvable as well.
<sharkdp> I will create a few follow-up tickets later today.
<triallax> i'll try it out in a bit
<sharkdp> I wrote a lot of new tests. All of the previously-existing ones are passing. But I'm sure we will still find a few bugs here and there, so please feel free to play around with this. And if you have some existing Numbat code, please check if it still works.
<sharkdp> There's also a breaking change concerning the definition of generic functions, most of which will now need `Dim` bounds. See https://numbat.dev/doc/example-numbat_syntax.html => my_sqrt for an example.
<sharkdp> I think there are also some cool follow-up tasks, like giving `quadratic_equation` a `List<…>` return type
<sharkdp> .. or turning the numerical_diff.nbt example into actual functionality within the prelude
Charbot9000 has quit [Remote host closed the connection]
Charbot9000 has joined #numbat
<achin> very cool, can't wait to play with it
<triallax> tried it out quickly, i love it
<achin> !nb fn average<T: Dim>(lst: List<T>) -> T = sum(lst) / len(lst)
<Charbot9000> fn average<A: Dim>(lst: List<A>) -> A = sum(lst) / len(lst)
<achin> !nb average
<Charbot9000> average = <function: average> [forall A: Dim. Fn[(List<A>) -> A]]
<triallax> very, very cool
<triallax> and it feels strange to be seeing a haskell-style function signature in numbat
<achin> it's clearly says it's a function, but it also re-uses the traditional [brace] syntax for listing the "dimension", which seems a little confusing
<triallax> you have a point
<triallax> also, would be nice if it preserved the names of the generics
<achin> !nb now()
<Charbot9000> now() = Tue, 4 Jun 2024 12:38:19 -0400 [DateTime]
<achin> seeing [DateTime] isn't confusing to me, because there's just one thing there. but there's a whole lot of syntax and symbols in the function example that somehow set it apart for me
<achin> but i do understand the desire to use consistant syntax. so i'm not sure if i'm proposing any type of change here. just making a personal observation
sharkdp has quit [Remote host closed the connection]
sharkdp has joined #numbat
<sharkdp> "would be nice if it preserved the names of the generics" => this is one of the open points, yes
<sharkdp> You can also just do:
<sharkdp> !nb fn avg(lst) = sum(lst)/len(lst)
<Charbot9000> fn avg<A: Dim>(lst: List<A>) -> A = sum(lst) / len(lst)
<sharkdp> And it will correctly infer the `A: Dim` bound, which is needed by `sum`. And the List<A> to A type for the function
<achin> ah, very nice
<achin> i think i might try to experiment with compiling numbat to a wasm to do hot-reloading within the bot
<achin> at the moment i have to restart the bot to get the latest version, which is not that suitable for the breakneck pace at which sharkdp is implementing features :)
<sharkdp> haha
<triallax> achin: word
sharkdp has quit [Remote host closed the connection]
sharkdp has joined #numbat
<sharkdp> I'm currently thinking that we are very close to implementing some really powerful things in Numbat
<sharkdp> (... there are two things that are really lacking: closures and local bindings ...)
<sharkdp> but even without them, we could start implementing things we talked about recently
<triallax> what's the finish line in mind here?
<sharkdp> Things I would really like to see:
<sharkdp> - parsing command line args in a nice way. maybe something like `let lengths: List<Length> = argv()` where `argv` would be polymorphic. Here, it would be instantiated as `argv::<Length>()` (a syntax that is not yet available). And we could then enter `1m 3inch 100cm` as arguments.
<sharkdp> - Plotting!
<sharkdp> - Simple I/O using CSV/JSON
<sharkdp> Concerning plotting, imagine:
<sharkdp> (I'm going to challenge the bot a bit)
<sharkdp> !nb fn _linspace_helper(start, end, n_steps, i) = if i == n_steps then [] else cons(start + (end - start) * i / (n_steps - 1), _linspace_helper(start, end, n_steps, i + 1))
<Charbot9000> fn _linspace_helper<A: Dim>(start: A, end: A, n_steps: Scalar, i: Scalar) -> List<A> = if (i == n_steps) then [] else cons(start + ((end - start) × i / (n_steps - 1)), _linspace_helper(start, end, n_steps, i + 1))
<sharkdp> !nb fn linspace<D: Dim>(start: D, end: D, n_steps: Scalar) -> List<D> = if n_steps <= 1 then error("Number of steps must be larger than 1") else _linspace_helper(start, end, n_steps, 0)
<Charbot9000> fn linspace<A: Dim>(start: A, end: A, n_steps: Scalar) -> List<A> = if (n_steps ≤ 1) then error("Number of steps must be larger than 1") else _linspace_helper(start, end, n_steps, 0)
<sharkdp> !nb let A0 = 3 cm
<Charbot9000> let A0: Length = 3 centimetre
<sharkdp> !nb let ω = 20 Hz
<Charbot9000> let ω: Time⁻¹ = 20 hertz
<sharkdp> let λ = 1.5 s
<sharkdp> !nb let λ = 1.5 s
<Charbot9000> let λ: Time = 1.5 second
<sharkdp> !nb fn amplitude(t: Time) -> Length = A0 exp(-t/λ) cos(ω t)
<Charbot9000> fn amplitude(t: Time) -> Length = A0 × exp((-t) / λ) × cos(ω × t)
<sharkdp> And then...
<sharkdp> !nb map(amplitude, linspace(0 s, 10 s, 100))
<Charbot9000> map(amplitude, linspace(0 second, 10 second, 100)) = [3 cm, -1.21842 cm, -1.63229 cm, 2.39077 cm, -0.515351 cm, -1.67091 cm, 1.80766 cm, -0.00795252 cm, -1.57343 cm, 1.28501 cm, 0.331382 cm, -1.39227 cm, 0.841281 cm, 0.53348 cm, -1.16861 cm
<triallax> heh
<triallax> very cool
<sharkdp> (oh, looks like the output is capped.. anyways)
<triallax> the output isn't capped, it's just that irc has a char limit for each message
<triallax> classic irc limitation
<sharkdp> I see
<triallax> maybe i should bridge this channel to matrix...
<achin> it's effectively a per-missage cat on line length, enforced by the irc servers
<achin> it doesn't help that these messages are highly colorful (since the color codes add to the message length)
<sharkdp> I think it's fine. We don't need to see the whole list :)
<triallax> obligatory xkcd: https://xkcd.com/1782/
<sharkdp> We could write that list of values to a file. And, crucially, also write out meta information that we have: function name, parameter names, parameter types, units..
<sharkdp> .. and use that to generate a plot including automatically generated axis labels
<sharkdp> Similar to what I did here: https://github.com/sharkdp/numbat/pull/147 -- but with much more support from the language
<sharkdp> But closures/lambdas are really a must-have in order for it to feel like a true functional programming language. `linspace` above would be much easier to implement with something like `map(|i| start + i * …, range(0, n))`
<sharkdp> typechecker-wise, we're all set for introducing them. everything is there already. but the VM implementation of closures is non-trivial (https://craftinginterpreters.com/closures.html) due to captures
<sharkdp> The other thing I'm really excited about is the typed-holes idea (https://github.com/sharkdp/numbat/issues/437)
<sharkdp> None of the calculators I know has a feature like this. But I think it would be really useful in practice.
<sharkdp> .. as in: when actually doing scientific calculations.
Charbot9000 has quit [Remote host closed the connection]
Charbot9000 has joined #numbat
<achin> btw, i saw this post the other day and thought it would be fun to replicate these formulas in numbat https://physics.stackexchange.com/questions/816698/how-many-photons-are-received-per-bit-transmitted-from-voyager-1
<sharkdp> Haha, had the exact same thought!
<sharkdp> !nb let f = 8.3 GHz
<Charbot9000> let f: Time⁻¹ = 8.3 gigahertz
<sharkdp> !nb let ω = 2π f
<Charbot9000> let ω: Time⁻¹ = 2 π × f
<sharkdp> !nb let λ = c / f
<Charbot9000> let λ: Length = c / f
<sharkdp> !nb let E_photon = ℏ ω
<Charbot9000> let E_photon: Length² × Mass / Time² = ℏ × ω
<sharkdp> !nb let P_transmit = 23 W
<Charbot9000> let P_transmit: Length² × Mass / Time³ = 23 watt
<sharkdp> !nb let d_voyager = 3.7 m
<Charbot9000> let d_voyager: Length = 3.7 metre
<sharkdp> !nb let R = 23.5 billion kilometers
<Charbot9000> let R: Length = 23.5 billion × kilometre
<sharkdp> !nb let irradiance = P_transmit / (4π * R^2)
<Charbot9000> let irradiance: Mass / Time³ = P_transmit / (4 π × R²)
<sharkdp> !nb let D_receiver = 70 m
<Charbot9000> let D_receiver: Length = 70 metre
<sharkdp> !nb let P_received = irradiance * (π d_voyager / λ)^2 * (π D_receiver² / 4)
<Charbot9000> let P_received: Length² × Mass / Time³ = irradiance × (π × d_voyager / λ)² × (π × D_receiver² / 4)
<sharkdp> !nb let num_photons = P_received / E_photon -> 1/s
<Charbot9000> let num_photons: Time⁻¹ = P_received / E_photon ➞ 1 / second
<sharkdp> !nb "Number of photons per second: {num_photons}"
<Charbot9000> "Number of photons per second: {num_photons}" = "Number of photons per second: 240188 s⁻¹" [String]
<sharkdp> Same result as the S.E. answer
<sharkdp> Would be cool to clean this up and add as a Numbat example
<sharkdp> And I should really fix the "readable types" feature, which I broke in the type inference PR. Otherwise, we wouldn't see things like `Mass / Time^3` above.. but `Irradiance`
<sharkdp> And for the cleaned-up example, we use `now()` to adjust the distance-to-earth :)
sharkdp has quit [Remote host closed the connection]