« first day (4408 days earlier)      last day (733 days later) » 

00:18
me when the theory of computation course introduces decision problems as a topic but I already know about challenges
okay so
I have decided that it'd be a bad idea to try to shoehorn my exciting new packaging system into Rol, so I will design (and *gasp* maybe even implement) my own language to use it with
presenting: Rabbit! Python, but Betterâ„¢
here's a sneak peek:
public class HelloRabbit:
	public static function main() -> int:
		print("Hello, Rabbit!")
(this is a WIP and subject to change)
(also cc @RydwolfPrograms)
00:42
@Ginger AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
what is this cursed mix of python and java
RABBIT
you shouldnt have to make a class just to have a main
just do public function main...
instead of a class
AND IT COMPILES TO VALA
java's lack of free functions is one of my biggest pet peeves
ooh, maybe I should do public static function main() returns int :p
01:01
@Ginger Classist OOP in 2023?
Who does that
me, because I'm a crazy b*tch
And if you're gonna do OOP, do it well, no offense
because you're an enemy of the proletariat
Just copying Java with some Python-y syntax brings nothing to the table
Look at all that boilerplate
We were supposed to bring balance to the verbosity, not wholeheartedly endorse it
ok, is this better:
function main():
	print("Hello World!")
01:03
considerably :P
Maybe do fn instead of function
Or fun(c)
I like function
So do I but the world is changing Ginger
We must adapt or die
Anyway gtg o/
I'll be back with more moderately solicited moderately good opinions within the next minute to decade
01:05
also, this is realistically the best you're going to get because I am 100% too stupid for type inference:
function main() -> int:
	print("Hello World!")
	return 0
@Ginger imo functions should not have type interence
explicit signatures should be encouraged at the top level but for anonymous functions you absolutely want inference
and if you're capable of inference for those you may as well allow it in general
maybe with a compiler warning attached or something
wait this language is interpreted why in the frick am I trying to make it statically typed
because static typing is categorically a good idea
01:17
fair enough
@Ginger imagine not allowing multiple words to be used
what
def main(): being the same as function main(): being the same as define main(): being the same as fn main():
NOOOOOOOOOOOOOOOOO
Yes
Allow the user to choose their verbosity
01:20
i'd also add that there are cases where long-term omitting a signature for a named function is reasonable or even desirable
specifically when you already would have to know it--i.e. typeclass/interface implementations and possibly entry points
@RydwolfPrograms how about this?
01:39
@ParclyTaxel it's also more exclusive here, since there are only 4 compared to 7 with 100K
@cairdcoinheringaahing just put their since he and her are already subsequences ;-)
@UnrelatedString ofc anonymous should have inference, i mean explicit
02:23
@Ginger I mean, you don't have a choice. You will die, and it'll be sooner than you might expect
._.
02:53
@lyxal #define function int
 
2 hours later…
05:00
0
A: Sandbox for Proposed Challenges

Parcly TaxelSimultaneously solve N-queens and no-3-in-line fastest-codechessgrid An intriguing MathsSE question asked if there were large N-Queens solutions where no three queens lie on a line. That question's body included the unique 4×4 solution up to symmetries . Q . . . . . Q Q . . . . . Q . and noted t...

First fastest code challenge from me. Anything I missed here?
 
2 hours later…
06:33
It looks fun!
What looks fun?
oright
:)
 
6 hours later…
12:13
here, have some more Rabbit:
public main function counting() -> int:
	(1..).map(print).collect()
	return 0
hey wait is that a function with side effects being lazy mapped over a collection?
ew
it sure is!
59 secs ago, by lyxal
ew
sue me
sure
Your honour, the defendant is clearly breaking all holy laws of functional programming and should be found liable for causing trauma and cringe to all who saw the snippet
12:18
We the judge find the defendant guilty, and sentence them to 5 minutes of rethinking their coding decisions
9
thank you, your honour
fine, here's a better version:
public main function counting() -> int:
	[print(i) for i in 1..]
	return 0
thank you
13:16
0
Q: Print "hello world" with as many bytes as possible

PixelbogWhere is the hard part you ask? Well just follow the rules... :) Rules: You can use every language you want Every instruction has to help you print out hello world You can only use 3 Math operands in total You can only use 3 variables in total All variable names should be exactly 1 byte long Var...

I would have vtc'd as dupe of biggest irreducible hello world
ok, here's a feature of Rabbit: no null/None/nil/whatever
we only use Rust-style results
(that's also why the main function doesn't return void)
also, type unions are done with or
so the signature of the main function is something like int or Result<T, E>
13:42
Uggghh
(moving to off-topic TNB...)
@Ginger The whole syntax with .map, collect, and 1.. looks extremely rust already
OK, is something mathsy on-topic here?
Arbitrary mathsy thing
@ParclyTaxel Depends
OK, here's the thing that irked me just now
4
Q: $\sqrt{a^2}$ in integrals

HfdssdjnsHello we all know that $$\sqrt {a^2}=|a|$$ so when we have $$a^2=5$$ that is $$|a|=\sqrt5$$ and $$a=\pm\sqrt5$$ but i very often see that when solving integrals only the positive value is usually considered, for eg. Here in this example since $$a^2=5$$ that means$$a=\pm\sqrt5$$ but the book cons...

I was the first to answer this. I said that "integral tables assume x-and-x"
Complaining about votes is explicitly forbidden though
13:57
@mousetail yeah, I'm also taking inspiration from Rust
okay, so I think I've figured out exactly how Rabbit's packaging system will work (cc @RydwolfPrograms)
basically, "repositories", which are module sources, can give modules to "libraries", which are module sinks, which can then "lend" modules to programs
it's hard to explain in words, so how about an example
suppose I have a bundle for a program called goat_recognizer
this bundle contains the goat_recognizer module, as well as a dependency (fancy_terminal)
Why not a traditional module system like rust?
because this is better
What concrete problem is it trying to solve with this extra complexity?
let me type please
the bundle also has a dynamic dependency (image_recognizer) which the creator of goat_recognizer has deemed too large to be bundled with the rest of the code
I find it very hard to visualize what you are trying to say without first knowing the problem
14:04
@mousetail I explained all of this already, let me find the link

Rabbit packaging

23 hours ago, 3 hours 21 minutes total – 313 messages, 16 users, 0 stars

Bookmarked 2 mins ago by Ginger

@mousetail ^ read that, it explains the basics of this system
I still don't understand why not normal packaging
what do you mean "normal"? there is no "normal" here
this system is specifically designed to fix Python's myriad packaging problems
You talk about big dependencies and locking specific verisons but normal packaging handles that just fine
28 secs ago, by Ginger
what do you mean "normal"? there is no "normal" here
I think you should read that convo first
Normal = Package file, lock file. Specify a version range
14:09
so, as I was saying
when you tell the packager to install a bundle, a few things happen
I tried to follow the conversation yesterday too but never understood why you would want to go through the effort
bundles are a form of repository according to the packager, so it looks at the file and sees that it's a repository containing one version each of goat_recognizer and fancy_terminal, with goat_recognizer being marked as a "main" module (which means the packager will try to install it)
so the packager adds the bundle to its repository list for this operation
Why not have goat_recognizer simply depend on fancy_terminal like a normal package manager?
then, it checks the dependencies. It needs to install goat_recognizer, fancy_terminal, and image_recognizer, so it looks at all of its repositories for those packages
goat_recognizer is only available in one repository: the bundle, fancy_terminal is available in both the bundle and a remote repository, and image_recognizer is only available in the remote repository
the packager will then install goat_recognizer from the bundle, download and install image_recognizer from the remote repository, and install fancy_terminal from whichever source supplies a newer compatible version (defaulting to the bundle's copy)
so now all three of those are in the library
Oh so the point is some kind of decentralized repository?
14:14
yes, kinda
so now we're done; the end-user can use goat_recognizer as normal
But why bundles then? Are they not the same as a repository in this sytem
now, I have to think about how the next part will work
gimme a sec
ok got it
so all of these modules are now installed in the global library of modules, and can be run from there
now suppose I want to set up a development environment with my own code
a big feature of the Rabbit interpreter is that it can take a path to a library as input (defaulting to the global library) and it will only import modules from that library
this is mainly useful for setting up a development environment
so now if I make a development environment, a new library is created by the build tools in my work folder, and all of my dependencies are symlinked in
(remember "library" in this context refers to a collection of modules, not a module itself)
it's kinda like the older "module group" system, but less redundant
Why the symlink though? Couldn't the interpreter read modules directly from the folder they are in
1 min ago, by Ginger
a big feature of the Rabbit interpreter is that it can take a path to a library as input (defaulting to the global library) and it will only import modules from that library
But symlinks would defeat that making the feature useless
14:20
and you probably don't want to put your development code in the global library, which may or may not be writable by you
so you make a "virtual library" for development and symlink in all the dependencies from the global library
I'm so confused. Why would you want to write to a library?
time to make a flowchart!
So this is a very complex way to test libraries you are writing?
@Ginger Is this for the dev or the end user
@Ginger What's the point of that?
All that does it restrict you, no?
It doesn't prevent any conflicts or anything assuming you're halfway sane and consider different versions of modules to be different modules
I'd even make them content-addressable, but that's maybe unnecessary
14:24
fair enough
I could pretty easily make the interpreter be able to use multiple libraries at once
Just. Make. It. Based. On. Modules. No additional organization.
Please
@Ginger wha-
Why
Just...use normal import statements
This whole thing feels like a solution in search of a problem
@RydwolfPrograms okay
I will do that
The whole "repository" thing is unnecessary
14:25
no libraries, no extra stuff, just modules
When you install goat_recognizer as a dev, the package manager checks its imports or its dependency lockfile or whatever, and then installs those
ok
@RydwolfPrograms what do you mean "unnecessary"? modules don't just appear from thin air
And just to clarify this whole repository system doesn't override how bundling works right
@Ginger No, they get installed
Individually
I think there's some confusion here
I think so
14:28
A module is just a folder with some source code and a list of requirements
so let me clear it up
"repository" is anything that can provide modules, which can be a website (like pypi) or a bundle file
ok?
Oh okay
Well then "libraries"
"libraries" are things that modules are installed into
and probably unnecessary for that matter
@Ginger The packager wouldn't exist on the end-user's machine right?
what do you mean?
14:30
I thought the whole point of this system was allowing the packages to be installed using a normal OS package manager or similar
If you already have a language-specific package manager on the end user's machine, bundling's totally unnecessary
uhhhh
You can just install all the dependencies normally
I'm confused
oh
I think this is supposed to be the normal pacakge manager for Rabbit right?
@RydwolfPrograms wait how would that work?
different linux distros have different package managers
14:31
My impression was that the Rabbit package manager would be for devs only, and bundles would be distributed independently from it
@Ginger Wdym?
How does that change anything
You can install php on both apt and dnf
So you could install goat_recognizer on both
I don't get it
what do you think a "bundle" is? a fancy .deb or what have you?
one file that multiple OS package managers can all install?
A program and all its dependencies compiled into a single file (excluding dynamically linked ones)
Which you could in theory put in an OS package manager
that'd be cool, but isn't possible
14:33
Like what you'd do with a compiled lang's code
@Ginger Why?
if I'm understanding correctly, you're suggesting that I should just be able to do apt install ./goat_recognizer.bun?
No ./
I'm talking about if it was in the apt repository
apt install goat_recognizer
problem: different package managers have wildly different repository formats
That'd install the .bun, and its apt depencies would include rabbit and image_recognizer
@Ginger It's already done, but often unreliable since OS package managers don't handle multiple versions of the same package
14:35
@Ginger You're not understanding me
so it seems
I'm not saying this would be like an unofficial deb
I'm saying it would be a package you'd install normally
Like, through the package manager
how??? apt can only install .deb files
that's it
AAAHHHHHHHHHHHHHHHHH
YES GINGER
You would create a .deb file, and put that in the apt repository
You would create a .rpm file, and put that in the dnf repository
You would create a .whateverthefuck and put that in the apk repository
Then you could run apt install goat_recognizer, and it would install that
but those aren't bundles! those are debs and rpms and whatever! those are not bundles! bundles are platform-agnostic!
14:37
Yes but that rpm would install the bundle
It would be in the rpm
I'm just saying that you could install the .bun without a Rabbit-specifc package manager
Forget the OS package managers
okay okay
OH I GET IT
that makes sense actually
so .bun files can be turned into .debs and .rpms and whatever?
Yeah, if you wanted to. Or I could go to gingers-shady-downloads.org and grab a .bun on my own
that makes sense, and gives me an actual reason to make them function as repositories!
14:39
But either way I don't need Rabbit's package manager
side note: Python tried to do this, and failed miserably
(and if end users were expected to have it, bundling would be totally unnecessary, since they could just run breed install goat_recognizer)
I can, if I want, install numpy from both apt and pip, and probably brick something
Yeah. Technically you'd be able to do that with this, but it'd be a huge pain
Since breed (that's what I'm naming your package manager sorry) won't automatically look inside that bun unless you tell it to
the manager will be called carrot
breed sounds disturbing
14:41
breed is so much better tho :p
"Breeding like rabbits"
It just makes sense
breed can be some other tool
What do packages do? They allow code to breed. They pass on their code to the next generation of programs.
it just sounds sleazy, and I don't want my language to be known as "the sleazy package manager language"
14:42
Carrot would be more like a linter or a formatting utility
yeah yeah fine :p
I think it's pretty funny tho lol
how about this: breed can be the internal dependency resolution engine
And you can't stop me from aliasing it in my bashrc for the rest of time
because you use carrots to breed rabbits, as Minecraft taught us
Okay I actually like that yeah
oh I just had an awful idea: newer versions of packages (since multiple can be installed at once) are diff files between the older package and the newer one
I will not be adding this but what if I did
14:44
That's an actually valid option I was gonna suggest
Well, not diff files
But maybe some sort of overlay filesystem for small updates, so that unchanged files don't have duplicate copies
Automatically hardlink identical files
sounds like ✨premature optimization✨
For sure
@mousetail That's probably a better way to do it yeah
Needing to install multiple versions should be a rare occurrence if packages properly set the ranges they can accept
14:46
okay, now that we have the package system nailed down, we just need to write the actual interpreter, which I'm sure will be the easy part :p
OverlayFS and similar can be weird to make backups of, and it would mean you can't run it in a Docker container
and by "we" I mean "I" unless anyone else is foolish enough to help
@Ginger I still don't understand it
I don't understand git, but I use it every day :b
@RydwolfPrograms so, in case you missed it, here's some preview WIP Rabbit code:
public main function counting() -> int:
	[print(i) for i in 1..]
	return 0
The return shouldn't be nececairy
what will it return then?
because implicitly returning 0 feels weird
A Never type specifically for this purpose
hm, like Rust's !?
Yep
Typescript has it too
Ehhh
main shouldn't return !
! is for things that panic or run infinitely
main usually does return
It should return ()
14:49
If main runs infinitely it should return !
So to make sure I understand this. Rabbit's package manager is called carrot. Carrot's a normal package manager, it just installs a module, then recursively installs its dependencies. A Rabbit program can be packaged into a single bundle containing all of its code and dependency modules, which is how you'd share the program with end user. Some modules can be dynamically linked, which would mean they're installed independently and shared between multiple programs.
@mousetail It makes no difference tho
@RydwolfPrograms correct
Nothing depends on main, so the compiler doesn't care whether it's ! or () if it doesn't terminate. If it does terminate, ! is actually wrong, unlike () for an infinite loop, which is valid but bad practice.
14:50
My main point is that the expression [x for i in 1..] should return ! and whatever comes afterwards doesn't matter to the type checker since it can't ever be called
remember: Rabbit is interpreted, not compiled
There is still a type checker that runs first though?
correct
actually, I'm considering making it so that Rabbit programs are "pseudo-built", Python-style, into a kind of optimized bytecode that can then be run by the interpreter
Yea in this case the type checker should ignore the lack of a return statement because the function can never exit. All valid code paths, which is none of them, return a value
The only reason to make main return ! is to make it easier for programmers
Since you don't need to worry about preventing it from returning something
Wait nvm
Semicolons exist
Or if they don't, you probably don't implicitly return the last statement's result
14:53
^
Returning () is returning nothing, returning ! is never returning
Are we talking about main in general or this specific example
Your statement about preventing it from returning something seems to apply mostly to (), not !
slight gripe: I don't like () as the "nothing" type
14:54
Why? It literally is nothing
A zero length tuple is no data
@Ginger Yea not a huge fan either
(in a compiled lang at least)
I don't like the fact that it's a tuple
Use nothing or similar then
a tuple, regardless of length, is not "nothing" to my brain
so I will make nothing a keyword, like true or false, and use it instead
14:55
But in a compiled lang a zero length tuple is literally zero bits
So it makes sense
it's not "nothing", it's "something about which there are no interesting properties"
ah yes, dirt
@pxeger In rust it's literally nothing
Yes when compiled it's represented by zero bits of memory
14:55
ok, here we go:
public main function counting() -> nothing:
	[print(i) for i in 1..]
but it is still an object that you can use
Most uses will be removed by the optimizer
bold of you to assume I have an optimizer
@mousetail Yeah, advantage of ! as the main return type is you can return anything from main without the compiler complaining
I think main should be special cased honestly
Doing pretty much anything to () is a no-op that will get compiled away
14:56
what should main be able to return? I'm thinking nothing or int or Result right now
I'm thinking nothing. Not nothing, nothing. No ->.
It should be special cased to be able to return either nothing, or never return, or an error if you do Rust-style ?
well, no -> implicitly represents nothing
For main it should be special cased
why?
I get nothing out of doing that
So infinite loops don't make the compiler complain
14:58
...it's not compiled q:
Interpreter
You know what I mean :p
hmm
(I also don't like ! as the "never" type, so never gets to be a keyword too)
A function that infinite loops should be able to return any type
That shouldn't even be a warning
I guess yeah
so like main is always assumed to return nothing or never unless you explicitly say otherwise?
14:59
Actually yeah mousetail's right
There is no real use returning never from main, since never is a instance of every possible type effectively

« first day (4408 days earlier)      last day (733 days later) »