Of course. I’ll try to find a more minimal example first.
@alexharsanyi has joined the channel
So, Racket is not really good at making small executables from small programs. For example:
• A simple 2 line hello world application will be 31Mb in size once you use raco exe and raco dist • My own application, which is 60′000 lines of Racket code, is 102 Mb in size when you use raco exe and raco dist, and 37 Mb of that are binary data files shipped with the application.
also, to compare executable sizes with other programs, another application with similar functionality, but written in C++ is close to 290Mb
so Racket produces competitive sized executables once you start making larger applications.
Got it. Thanks! Would 50MB be a deal-breaker for you, for a simple CLI utility? Is there any other lisp that you can recommend for CLI utilities?
I don’t know, gcc
is a command line utility, yet is quite large…
Right. What about something like a grep clone?
Another way to look at it is that I have 230Gb free disk space on my laptop, so 50Mb is really nothing… Even on my 6 year old Raspberry PI, I still have 5Gb of free space so 50Mb would still be nothing…
… although 50Mb would be too large for my Arduino boards :grin:
Out of curiosity, I checked the size of the grep
program that comes with my git for windows git installation. While grep.exe
itself is only 250kb, it actually uses some of the msys libraries, including the pcre library which is probably used for regexp matches. Adding together the libraries used directly (without which grep.exe would not run), they total about 6Mb — there would probably be additional libraries needed to be able to run grep standalone on windows, so the size of the grep written in C is not tiny either…
Are there lectures about when is imperative programming in Racket recommended?
I mean, imperative programming can speed up some algorithms. I think i could taking advantage of imperative programming in some sotuation and create a functional procedure (but internally imperative)
I think it says what you already said, but there is https://docs.racket-lang.org/guide/performance.html#%28part._.Mutation_and_.Performance%29
which has a link also to https://docs.racket-lang.org/guide/set_.html#%28part._using-set%21%29
My rule of thumb is to write things without mutation, until/unless I know that mutation would make it faster, and that the code in question even really needs to be faster.
You also touched on a great point, about encapsulating or localizing it: Keeping mutation local within an otherwise observably functional wrapper.
Which in general (not just wrt mutation) is a wonderful situation when you can arrange it: Being able to tweak the implementation of something without anything else needing to know or care.
But I think this is all Captain Obvious stuff you already know. :slightly_smiling_face: If someone else has a link to a better discussion, I’d love to read that, too.
Thank you! I have tried to program in a functional way always, but sometimes the imperative solution is so obvious, but then I remember Racket discourage it :laughing:
“While side effects are to be avoided, however, they should be used if the resulting code is significantly more readable or if it implements a significantly better algorithm.”
:ok_hand::skin-tone–2:
yeah i had this issue too with small CLI applications too lol… if only racket was as popular as python i could just ship the script..
A while ago I wrote a blog post about optimizing a program that ran in 8 seconds on average to one that ran in 33 milliseconds on average — there is a summary of the techniques used at the beginning of the post, which you may find useful: